s&box/field-guide
the symptom, in your words

"Blender OBJ export face order is not deterministic"

✓ verified on engine 26.07lane: Getting art inposted
▸ SYMPTOM

Running the exact same headless Blender script twice on the same mesh produces OBJ files that differ at the byte level. Vertex, normal, and UV data are identical, and face count matches, but the f lines come out in a different order — typically on the highest-polygon-count mesh in the batch.

▸ CAUSE

bpy.ops.wm.obj_export appears to have an internal multithreaded polygon-list writer whose iteration order is non-deterministic. The geometry itself (vertex positions, triangle count, bounding box, material assignment) is bit-for-bit identical across runs — only the serialization sequence of face lines varies.

▸ FIX

Do not chase OBJ-file byte-identity as a determinism proof for your pipeline. Instead:

  1. Diff the manifest / census data — bounding boxes, triangle counts, material assignments, world-space sizes. These hold deterministically.
  2. Expect occasional face-order churn on any high-poly-count single mesh in a scripted OBJ export batch.
  3. If byte-identical output matters (e.g. for content-addressed caching), sort f lines post-export or switch to a format with a defined face order.
▸ WHY IT WORKS

The geometry-level determinism that matters for an art pipeline (correct scale, correct tri count, correct material) is solid. The face-line ordering is a serialization detail that does not affect the imported model in-engine.

Verified on engine 26.07 — seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?