The rules the public API of oxijolt follows from 1.0 on. New code follows them; a change that
breaks one needs a reason written next to it. The Rust API Guidelines
(https://rust-lang.github.io/api-guidelines/checklist.html) apply where these rules say nothing.
- Type and method names keep Jolt's words in Rust case.
IDbecomesIdandDOFbecomesDof(BodyId,SubShapeId,SixDofConstraint,AllowedDofs). - Jolt's C++ prefixes
E,sandmare dropped. - Abbreviations follow Jolt, spelled out where Jolt spells them out:
inverse_mass, notinv_mass. - A name leaves Jolt's only to avoid a clash or to name a Rust concept (
WorldState).
- Values are built with
Type::new(..)orType::new_<variant>(..). Shapes are alwaysShape::new_<kind>, decorators included (new_scaled,new_offset_center_of_mass). - Variants of a constructor add suffixes in this order:
_with_convex_radius, then_with_material(one&PhysicsMaterial, last argument), then_with_settings(a settings struct by reference, last argument). A constructor without a suffix uses Jolt's default for what the suffix would add. - Objects the world owns are made with
PhysicsWorld::create_<object>(..), which returns a typed id, and are removed withremove_<object>.
<Thing>Settingshas private fields, aDefaultequal to Jolt's defaults, and consuming#[must_use]setters named after the field. A flag setter takes abool.- Settings that need an input with no useful default (a character's shape, a wheel's position,
a vehicle's wheels and collision tester, a path, the centre of debug lines) take it in
new(..)and have noDefault. The settings a listener receives (ContactSettings,CharacterContactSettings,SoftBodyContactSettings) come from Jolt with the call. - Presets are named constructors (
humanoid,car,bike). - Plain-Rust settings are checked by the call that consumes them and fail with that call's error. Jolt-backed immutable objects are checked when they are built.
- Optional per-element data, such as materials, is a settings setter, never a positional argument.
world.<object>(id)returnsResult<<Object>Ref, <Area>Error>andworld.<object>_mut(id)returnsResult<<Object>Mut, <Area>Error>.- Getters have no
get_prefix. Boolean getters start withis_,has_orcan_. - Setters on live objects are
set_<field>and returnResultwhen they check their input. - A world collection lists its ids with
<object>_ids(), which returns an iterator (impl Iterator<Item = <Object>Id>), counts them with<object>_count()and tests one withcontains_<object>(id): bodies, characters, vehicles, ragdolls and constraints.
as_borrows and costs nothing,to_allocates,into_consumes.- A call that fills a caller's buffer is
<name>_into(&self, .., out: &mut T), next to an allocating<name>. - No other out-parameters: return values, iterators or slices.
- One
<Area>Errorper area, inerror.rs. Each is#[non_exhaustive]andClone + Copy + Debug + PartialEq + Eq.Copyis a 1.0 commitment: payloads are&'static str, ids, numbers orJoltMessage. - A value out of its range is
InvalidValue(&'static str)in every area. - A native allocation that fails is
AllocationFailed; a refusal Jolt reports isRejected(JoltMessage). - A body problem found by another area is
<Area>Error::Body(BodyError). An error that wraps another returns it fromsource(). - The umbrella
error::Erroris transparent: itsDisplayandsource()are those of the area error it holds, so an error report does not print that error twice. Get the area error with amatch, not fromsource(). Displayis lowercase, one clause, without a trailing period.- Fallible public calls return
Resultand do not panic on caller input;expectis for internal invariants only.
- Every public type implements
Debug(the crate sets#![warn(missing_debug_implementations)]). Handles show their id; wrappers of native objects usefinish_non_exhaustive. - Ids are
Clone + Copy + PartialEq + Eq + PartialOrd + Ord + Hash. - Readouts, events and settings are
Clone + PartialEq, andCopywhen they hold no heap data and no Jolt reference. Settings areDefaultunless R3 says otherwise. - Settings that borrow a
Shapeor aPhysicsMaterial(CharacterSettings,MeshSettings) or hold the caller's job system (WorldSettings) are notPartialEq: shapes, materials and job systems have no equality.RagdollSettingsandSoftBodySharedSettingsare built Jolt objects, not settings in this sense. tests/api_traits.rschecks these traits at compile time.
- On every error enum, every pub-field readout or event struct the crate produces, and every enum Jolt may extend (sub-types, results).
- Enums that mirror a closed Jolt enum stay exhaustive:
MotionType,MotionQuality,Activation. - Pub-field structs and enums the caller writes as literals stay exhaustive (
CompoundChild,ContactPoint, input vertices,RagdollJoint).
- Counts of world objects and of Jolt indices (bodies, constraints, wheels, parts, joints,
sub-shapes) are
u32, Jolt's own index type. - Counts and indices of caller-indexed buffers (vertices, faces, triangles,
DroppedTriangles::count) areusize.
- Physical magnitudes live in
limits. - Per-type capacities and Jolt defaults are associated consts of their type
(
WorldSettings::MAX_BODIES,WheelSettings::DEFAULT_LATERAL_FRICTION). - Nothing else sits at the crate root.
- The root is flat: modules are private except
error,limitsandprelude(withprelude::math). - The root names nothing that common globs export besides the math types (
Vec3,Quat,Real,RVec3);ErrorandResultstay inerror. - The prelude holds the types most programs name (world, bodies, shapes, layers, queries, events,
ids, the settings of the main objects, every area error) and no math type or
Result, so it can be glob-imported next tobevy::prelude::*.tests/prelude.rsandtests/root_glob.rsguard this.
- Features are additive, except
double-precision, which changesRealin every signature. Only the final application enables it; libraries built onoxijoltforward it. bindgenis a build switch outside the semver promise.- A feature for a public dependency carries the dependency's version in its name (
glam032), so a later version can be added next to it in a minor release.mint(0.5) keeps its name.
rust-versionin both crates'Cargo.tomlis the MSRV; CI checks the workspace with that toolchain.- The MSRV is at least six months old. Raising it is a minor release, noted in the changelog.
- Edition 2021.
#![warn(missing_docs)]; CI turns warnings into errors.- Every public item states its units, conventions and errors (
# Errors). Everyunsafe fnhas a# Safetysection. - Measured numbers live in
docs/, linked from the rustdoc.