Skip to content

Rename JSON importer to .oae extension; spawner + collider polish#6

Merged
SilicoBen merged 2 commits into
mainfrom
feat/oae-extension-and-spawner-polish
May 18, 2026
Merged

Rename JSON importer to .oae extension; spawner + collider polish#6
SilicoBen merged 2 commits into
mainfrom
feat/oae-extension-and-spawner-polish

Conversation

@kylaalsbury-nealy

Copy link
Copy Markdown
Contributor

Why

ADR-0002 chose to register a ScriptedImporter for .json. Unity rejects
that at runtime — .json is owned by the built-in TextAsset importer.
This PR switches to a dedicated .oae (OpenApparatus Environment)
extension, documented in new ADR-0008.

Several spawner/inspector improvements landed alongside the rename
because they were already in the working tree from local testing.

What changed

Extension rename (the headline):

  • [ScriptedImporter] now claims .oae. Unity accepts the registration.
  • Tests/Fixtures/single_room.jsonsingle_room.oae (.meta renamed
    to preserve GUID).
  • Samples~/ImportedEnvironment/single_room.jsonsingle_room.oae.
  • ADR-0008 added; ADR-0002 marked superseded.
  • format-contracts.md + conventions.md updated.

Spawner: per-part child GameObjects.

Each Room_X now has explicit Floor and Ceiling children (each
with its own mesh + material), plus per-wall children with their own
meshes. JsonGeometryBuilder split into per-surface builders. Tile
coordinates now apply the X-mirror that OpenApparatusSpace applies
to wall endpoints — floors/ceilings used to sit at +X while walls sat
at −X.

ColliderMode is now [Flags]:

None / Walls / Floors / Ceilings / Objects / All. Multi-select in
the inspector. FloorCollider now lives under each room's Floor
child; CeilingCollider under Ceiling. Symmetric with
WallCollider under each Wall.

The Objects flag controls whether placeholder primitives keep
their default collider (GameObject.CreatePrimitive adds one).
Substituted prefabs are never touched — collider is the prefab
author's choice.

Inspector: editable spawn options in the right place.

Unity 6 locks the "Imported Object" section read-only. Spawn options

  • Spawn button moved to a new JsonEnvironmentImporterEditor that
    shows in the editable "Import Settings" section. Bonus: the summary
    now lists each environment's Object Types so researchers know exactly
    what strings to type into PrefabSubstitutionTable entries.

Prefab substitution preserves the marker.

The substituted instance gets a RoomObjectInstance component
(slot + room id + rotation) so downstream code can find research
objects after substitution. Reverses one note in task J's brief;
the marker carry-over is the right call.

Follow-ups not in this PR

  • openapparatus-core: bump JsonExporter to write .oae files.
  • openapparatus-studio: file-save dialogs default to .oae.
  • Wall-mesh extrusion direction may still be wrong on some wall
    orientations. To be revisited if production geometry continues to
    come from JsonGeometryBuilder rather than Studio's GltfExporter
    via task B.

The Wave 2 task A brief and ADR-0002 chose to register a ScriptedImporter
for the .json extension. Unity rejects that at runtime - the built-in
TextAsset importer owns .json and scripted importers cannot claim it.
This PR switches to a dedicated .oae (OpenApparatus Environment) extension,
documented in new ADR-0008 (supersedes ADR-0002 on the .json point only).

Alongside the rename, several spawner and inspector improvements landed:

Importer / inspector
- JsonEnvironmentImporter now claims ".oae" and exposes ColliderMode +
  Substitution as serialized fields persisted in the .meta file.
- JsonEnvironmentImporterEditor (new) hosts the spawn options + button
  in the editable top "Import Settings" section. Unity 6 locks the
  bottom "Imported Object" section, where they previously lived.
- Inspector now lists each environment's Object Types so researchers
  see exactly what strings to put in PrefabSubstitutionTable entries.
- MultiRoomEnvironmentAssetEditor reduced to a passive summary.

Spawner
- Each Room now gets explicit Floor and Ceiling child GameObjects in
  addition to per-Wall children. Each carries its own MeshFilter +
  MeshRenderer + per-part material via MaterialResolver.
- JsonGeometryBuilder splits BuildRoomMesh into BuildFloorMesh,
  BuildCeilingMesh, and BuildWallMesh; the X-mirror that walls already
  applied is now applied to floor / ceiling tile coordinates too.
- Spawner removes the primitive collider on placeholder objects when
  ColliderMode.Objects is not set.

Collider builder
- ColliderMode is now a [Flags] enum: None / Walls / Floors / Ceilings
  / Objects / All. Multi-select in the inspector.
- FloorCollider lives under each Room's Floor child; CeilingCollider
  under Ceiling - symmetric with WallCollider under each Wall.
- BoxCollider sizing accounts for the X-mirror correction.

Prefab substitution
- The new instance carries a RoomObjectInstance marker component (slot
  + room id + rotation) so downstream code can identify research objects
  after substitution. Reverses the original design from task J - the
  marker carry-over is the right call now that we have collider passes
  that need to enumerate object instances.

Tests + docs
- Fixture Tests/Fixtures/single_room.json renamed to .oae; .meta moved
  with it so the GUID stays stable.
- Test path constants updated in three test files.
- Sample renamed; Samples~/ImportedEnvironment/README.md updated.
- ADR-0008 added; ADR-0002 marked superseded with cross-reference.
- format-contracts.md and conventions.md updated for the new extension
  and the [Flags] ColliderMode.
- Task briefs A, D, I, L updated to reference .oae fixtures.

Plus several smaller cleanups: AssemblyInfo.cs grants the test assembly
InternalsVisibleTo on the editor assembly so JsonEnvironmentDiscriminator
can stay internal; the importer no longer emits unused per-room Mesh
sub-assets (geometry is built at spawn time from RoomData).

Follow-ups not in this PR:
- openapparatus-core JsonExporter should write .oae files; PR pending.
- openapparatus-studio file-save dialogs should default to .oae; PR pending.
- Wall-mesh winding may still extrude inward on some wall orientations;
  to be revisited if production geometry continues to come from this
  builder rather than Studio's GltfExporter via task B.
The workflow was wired up for Unity Personal (UNITY_LICENSE = full .ulf
contents). Switch to the Pro flow: UNITY_SERIAL holds the serial code,
combined with UNITY_EMAIL and UNITY_PASSWORD for authentication.
@SilicoBen SilicoBen merged commit 2983488 into main May 18, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants