Skip to content

v0.1.0

Choose a tag to compare

@rawframe-release rawframe-release released this 24 Oct 15:11
cb2bf6e

0.1.0 (2026-10-24)

Changed

  • Breaking: the family API shape. m3CreateWorld returns
    m3Result and hands the world back through an out parameter, and
    every call takes the world first; readers take const m3World*.
    m3WorldId, m3World_IsValid, m3Body_GetWorld, m3Shape_GetWorld,
    m3Joint_GetWorld, m3SetAllocator, m3SetAssertHandler and
    m3LastResult are removed; the allocator is part of m3WorldDef,
    which begins with internalValue, version and loses workerCount.
    Every create and destroy returns m3Result, with the id in an out
    parameter (null on failure). A destroy of a stale id returns
    m3_errorStale, and a destroy of the null id returns m3_errorInvalid.
    Ids are {index1, generation}. Snapshots, restores, the journal calls
    and the replay container codec return m3Result, and
    m3World_RebuildBroadphase does too. Journal tapes recorded with
    0.0.1 no longer replay, and the replay container is version 2.
    (#13)
  • Breaking: hulls. Hulls are built from welded points (points
    within 512 QuickHull tolerances of an earlier point, about 1e-3 of the
    summed extents) with planes worked in double precision, so a cloud of
    near-duplicate points now gives a valid hull. Hulls built from the
    same points can differ from 0.0.1's, so the hashes and trajectories of
    scenes with hulls change. Snapshots are format 2: m3World_Restore
    refuses format 1, and replay files that hold one, with
    m3_errorInvalid.
    (#34)
  • Breaking: the world hash now covers every id pool's identity, a
    height field shape's grid, a body's gravity scale and dampings, a
    joint's limits, motor and collide-connected flag, and a mesh's painted
    materials, so state the step reads can no longer differ under equal
    hashes. Every world's hash changes.
    (#22)
  • Breaking: refusals. Arguments the engine cannot simulate are now
    refused at creation with m3_errorInvalid, and they count as misuse.
    This covers coordinates, half extents and local positions beyond 1e4,
    densities above 1e6, non-finite joint limits and rope lengths, soft
    body pressure above M3_SOFTBODY_MAX_PRESSURE, and the other bounds
    the headers list. A stale id or a refused argument counts as misuse in
    every call. A writer called while Step or Draw runs changes
    nothing and counts as misuse.
    (#14,
    #19)
  • Breaking: what a restore or replay accepts. m3World_Restore
    leaves the world unchanged and returns m3_errorInvalid for content
    the builders would not make (hull planes, mass and vertices; height
    field and mesh content), and m3_errorCapacity when the allocator
    refuses. Before, it could land such content or leave the world half
    restored. m3World_ReplayJournal refuses an op the public call would
    refuse. It returns m3_errorCapacity with the world as it was when
    memory runs out. To do that it reserves its memory up front, so a
    replay that fit a tight allocator before can now be refused before any
    op runs.
    (#27,
    #29,
    #30,
    #33)
  • The library is built as C23 and needs GCC 14 or Clang 19 or newer.
    On Windows it is built with clang-cl. The public headers stay C17 and
    C++17, and MSVC's cl still compiles them. A shared library's
    SOVERSION is the whole version, and the CMake package accepts only its
    exact version, since before 1.0 any release may change the ABI.

Fixed

  • A mesh or voxel chunk whose tree cannot be built is refused with
    m3_errorCapacity, where before it was created and collided with
    nothing.
  • An explosion applies to shapes in slot order, so the result no
    longer depends on the broadphase's internal order.
  • The broadphase rebuild takes its scratch memory before recording
    itself, and records nothing when that fails.
  • Two joints that can never both hold no longer risk turning the world
    to NaN. Every joint row holds its accumulated impulse within a bound
    no ordinary scene reaches.
  • Replaying a damaged journal no longer reads a body def flag holding a
    byte other than 0 or 1, which was undefined behavior. A mesh's
    materials are recorded without an allocation.
  • A damaged snapshot whose voxel chunk count disagrees with its
    occupancy bits is refused.