You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refused by name in ADR-0013, split out of #322 (p6-s8).
Why it is refused rather than absent
p6-s8 reads glTF and GLB, and it does so for free: tinygltf is already pinned,
already linked on roadmaker_core, and its read side already compiles. OBJ has no
such free path. Realignment Q7 (2026-07-20) put it plainly — "OBJ: out unless
you want a new pinned dep (tinyobjloader, MIT) — not 'cheap' enough to smuggle
in."
So this is a dependency decision wearing a format request, and it belongs to a
sprint that can pay the dependency policy's price in full: a pinned tag and URL_HASH in cmake/deps.cmake, a THIRD_PARTY_LICENSES.md row in the same
commit, a license review, and a build-cost measurement. That is exactly the
reasoning ADR-0012
applied to zlib: the part we actually want drags in work that belongs to another
sprint, and taking it here would be taking it badly.
The practical cost of the refusal is low. OBJ→glTF conversion is a one-line job in
every DCC tool and in obj2gltf, and the refusal diagnostic says so, names
tinyobjloader as what would be needed, and cites this issue.
Scope
Pin tinyobjloader (MIT) with an exact tag + URL_HASH; add the THIRD_PARTY_LICENSES.md row in the same commit; measure the build-time cost.
A reader behind the existing extension dispatch in the prop importer, producing
the same PropModel. Nothing downstream of the importer learns a second format
exists — that boundary already exists by construction.
Extend is_prop_model_extension() and the file dialog's filter together — they
must not be able to disagree.
Fuzz-adjacent malformed-input tests, matching the glTF reader's.
Note
scripts/gen_prop_meshes.py already writes assets/library/props/<id>.obj + .mtl as inspectable reference output that nothing reads. Those files become a
ready-made round-trip fixture for this reader — and a good oracle, since the
kernel already holds the exact geometry they were written from.
Refused by name in ADR-0013, split out of #322 (
p6-s8).Why it is refused rather than absent
p6-s8reads glTF and GLB, and it does so for free: tinygltf is already pinned,already linked on
roadmaker_core, and its read side already compiles. OBJ has nosuch free path. Realignment Q7 (2026-07-20) put it plainly — "OBJ: out unless
you want a new pinned dep (tinyobjloader, MIT) — not 'cheap' enough to smuggle
in."
So this is a dependency decision wearing a format request, and it belongs to a
sprint that can pay the dependency policy's price in full: a pinned tag and
URL_HASHincmake/deps.cmake, aTHIRD_PARTY_LICENSES.mdrow in the samecommit, a license review, and a build-cost measurement. That is exactly the
reasoning ADR-0012
applied to zlib: the part we actually want drags in work that belongs to another
sprint, and taking it here would be taking it badly.
The practical cost of the refusal is low. OBJ→glTF conversion is a one-line job in
every DCC tool and in
obj2gltf, and the refusal diagnostic says so, namestinyobjloader as what would be needed, and cites this issue.
Scope
URL_HASH; add theTHIRD_PARTY_LICENSES.mdrow in the same commit; measure the build-time cost.the same
PropModel. Nothing downstream of the importer learns a second formatexists — that boundary already exists by construction.
.mtlmaterial colours map to the same flat per-part colour glTF'sbaseColorFactordoes. Texture handling follows whatever#507 has settled by then; if
p6-f2: imported prop textures — UVs and base-colour images through PropPart, the batch path and both exporters #507 has not landed, OBJ flattens exactly as glTF does and warns the same way.
is_prop_model_extension()and the file dialog's filter together — theymust not be able to disagree.
Note
scripts/gen_prop_meshes.pyalready writesassets/library/props/<id>.obj+.mtlas inspectable reference output that nothing reads. Those files become aready-made round-trip fixture for this reader — and a good oracle, since the
kernel already holds the exact geometry they were written from.