Repository navigation
v0.2.0
0.2.0 (2026-10-24)
Added
- 32-bit x86 builds. The
linux-i686-gcc-14and
linux-i686-clang-20presets build for i686 with
-m32 -msse2 -mfpmath=sse, and CI runs both. A host's own i686 build
needs those flags too: the library refuses to build with x87 float
arithmetic.base.haddsM3_ALIGN8, which the public headers use to
give 64-bit members 8-byte alignment.
(#41,
#44)
Changed
-
Breaking, on 32-bit x86 only: the public ABI. i686 hosts must
rebuild against the new headers. The doubles and 64-bit integers of
m3Pos3,m3QueryFilterand the body, character, soft body, vehicle
and shape defs are now 8-byte aligned there, as on every other target.
These public structs change size on i686:m3BodyDef, 108 to 120 bytesm3CharacterDef, 68 to 72m3ShapeDef, 92 to 104m3VehicleDef, 460 to 464m3WaterVolumeDef, 76 to 80m3JointDef, 216 to 224m3RayCastResult, 52 to 56m3BodyMoveEvent, 52 to 56m3FragmentEvent, 68 to 72
Every other public struct that holds an aligned member keeps its size
and changes only its alignment, from 4 to 8. An i686 tape recorded
with 0.1.x is refused withm3_errorInvalidwhen it holds one of the
twelve journal records whose size changed: a body, character, vehicle,
water volume or joint create, any shape create, a filter change, or a
force or impulse at a point. Other i686 tapes, and every i686
snapshot, still load. On x86-64, arm64, Windows and wasm nothing
changes but tape padding (below): existing tapes and snapshots load as
before.
(#44)
Fixed
- Journal tapes have one layout on every target. Before, a tape's
records were laid out as the recording target laid out its structs,
so a tape recorded on i686 was refused on x86-64 and the other way
round. Every journal record and every type a snapshot walks now has
its x86-64 layout on every target, and the build checks each size and
member offset, so a target that would lay one out otherwise fails to
compile. The formats are little-endian, and a big-endian target fails
to build.
(#44) - A tape's padding bytes are always zero, on every target. A create
copied the caller's def into its record whole, so the tape's padding
bytes held whatever the host left in the def's padding. Records now
copy each def member by member into zeroed storage. Replay never read
that padding, so worlds are unchanged, but the bytes of a tape can
change for a host that left anything there, and the same calls now
write the same tape.
(#44) - The misuse and busy counters are atomic on 32-bit x86. Their
64-bit atomics were 4-byte aligned on i686: clang could not make them
lock-free and the build did not link, and under GCC they were not
guaranteed atomic. Both counters are now 8-byte aligned on every
target.
(#41) - A 32-bit build no longer gets AVX2. The AVX2 backend was chosen
from the host's processor name, so an-m32build on an x86-64 host
was built for AVX2. It is now chosen only for 64-bit builds.
(#41)