Native core
native/activerse-core is a Rust crate with library name activerse_core. The release
build produces libactiverse_core.dylib on macOS, libactiverse_core.so on Linux, and
activerse_core.dll on Windows. mvn compile runs cargo build --release
in that directory. Java loads it with SymbolLookup.libraryLookup from
native/activerse-core/target/release, or from -Dactiverse.native.path /
-Dactiverse.native.dir.
What Rust owns
| Piece | Rust | Java keeps |
|---|---|---|
now_ns | Monotonic Instant | GameLoop samples it once as frameNs |
| Input ring | Samples of mouse, key, and button, each with t_ns | Bindings, chat text, UI edges |
integrate_to | 1 ms steps up to frameNs, 250 ms cap | When the sim is enabled |
| Character step | Wish, gravity, jump, coyote while enabled | The durations and the policy |
| Voxel mirror | Chunk bytes and material table for collision | The source chunks, meshes, saves |
Rendering, audio, UI, commands, inventory, and Actor.act are not in this crate. Do not move them
here to “make the frame faster.” The frame is already timed by this clock. Draw time is the GPU and vsync.
How a call crosses
NativeCore is the only Java type that should invoke the library. It keeps one session for the
process, created at class init. Methods take primitives and a packed 80-byte body (20 fields, 4 bytes each,
no padding): position, velocity, acceleration, size, eye height, ground and fluid flags, then surface and
fluid coefficients.
GameLoop is the caller of integrateTo. A world enables the step by publishing a
controller, which calls setSimEnabled(true). Game code that only needs a timestamp calls
NativeCore.nowNs(). Everything else on NativeCore is for the loop, the controllers,
and ChunkStore.
The input ring holds 4096 samples. A push past that returns 1 and drops the new sample. Key state is updated
as samples arrive, then rewound and replayed inside integrate_to so a press is applied on the
millisecond it happened, not for the whole frame.
Build and check
cd native/activerse-core
cargo test
# from the engine root
bash generate-javadoc.sh
mvn test
Rust tests cover the clock anchor, a one-millisecond key press, look sums, a fall onto a mirrored floor, and
a single 1/60 s step against the Java gravity formula. Java tests in
PhysicsEngineNativeParityTest compare one explicit dt with the Java reference for
a fall, a floor hit, a sprint wish, a jump, and water.
NativeCore.reset() clears the ring, the character, the clock anchor, and the voxel mirror.
Tests call it. A running game must not. ChunkStore.clear() drops mirrored chunks without
resetting the clock.