From fa15c0f40d57aaf5b704fe656b1bb716d7ded979 Mon Sep 17 00:00:00 2001 From: Benjamin Alsbury-Nealy Date: Mon, 18 May 2026 20:50:33 -0400 Subject: [PATCH] Add identity fields to placed objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each RoomObject now carries GlobalId, TypeId, CustomId and Name — user-editable identity strings with sensible placement-time defaults. Uniqueness is not enforced; two objects may legitimately share any field. The fields round-trip through the .oapp project format (ObjectInstanceEntry) and appear in the exported apparatus JSON for both in-room and outside objects. --- src/OpenApparatus.IO/Exporters/JsonExporter.cs | 12 ++++++++++++ src/OpenApparatus.IO/ProjectFile.cs | 4 ++++ src/OpenApparatus.IO/RoomObject.cs | 14 ++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/OpenApparatus.IO/Exporters/JsonExporter.cs b/src/OpenApparatus.IO/Exporters/JsonExporter.cs index 164ea97..322e789 100644 --- a/src/OpenApparatus.IO/Exporters/JsonExporter.cs +++ b/src/OpenApparatus.IO/Exporters/JsonExporter.cs @@ -168,6 +168,10 @@ public static EnvironmentDocument BuildDocument( Slot = o.Slot, Position = new[] { o.Position.X, o.Position.Y, o.Position.Z }, Rotation = o.Rotation, + GlobalId = o.GlobalId, + TypeId = o.TypeId, + CustomId = o.CustomId, + Name = o.Name, }); } entry.Objects = objList; @@ -193,6 +197,10 @@ public static EnvironmentDocument BuildDocument( Slot = o.Slot, Position = new[] { o.Position.X, o.Position.Y, o.Position.Z }, Rotation = o.Rotation, + GlobalId = o.GlobalId, + TypeId = o.TypeId, + CustomId = o.CustomId, + Name = o.Name, }); } if (outsideList != null) @@ -360,6 +368,10 @@ public sealed class ObjectInstanceEntry public int Slot { get; set; } public float[] Position { get; set; } = System.Array.Empty(); public float Rotation { get; set; } + public string GlobalId { get; set; } = ""; + public string TypeId { get; set; } = ""; + public string CustomId { get; set; } = ""; + public string Name { get; set; } = ""; } public sealed class ShapeSection diff --git a/src/OpenApparatus.IO/ProjectFile.cs b/src/OpenApparatus.IO/ProjectFile.cs index 7182d76..2686386 100644 --- a/src/OpenApparatus.IO/ProjectFile.cs +++ b/src/OpenApparatus.IO/ProjectFile.cs @@ -109,4 +109,8 @@ public sealed class ObjectInstanceEntry public float Y { get; set; } public float Z { get; set; } public float Rotation { get; set; } + public string? GlobalId { get; set; } + public string? TypeId { get; set; } + public string? CustomId { get; set; } + public string? Name { get; set; } } diff --git a/src/OpenApparatus.IO/RoomObject.cs b/src/OpenApparatus.IO/RoomObject.cs index 07a3429..441dcf6 100644 --- a/src/OpenApparatus.IO/RoomObject.cs +++ b/src/OpenApparatus.IO/RoomObject.cs @@ -8,6 +8,11 @@ namespace OpenApparatus.IO; /// re-evaluated on Rebuild() so an object whose room shrinks or moves is /// reassigned to whatever room now contains its world position. /// is a 1-based index into the VM's ObjectTypes list. +/// +/// , , and +/// are user-editable identity strings. They get sensible +/// defaults at placement time but uniqueness is not enforced — two objects +/// may legitimately share any of them. /// public sealed class RoomObject { @@ -15,6 +20,15 @@ public sealed class RoomObject public int Slot { get; set; } public Vector3 Position { get; set; } public float Rotation { get; set; } + + /// Per-apparatus running index, assigned at placement (0, 1, 2…). + public string GlobalId { get; set; } = ""; + /// Per-type running index, assigned at placement (0, 1, 2… within the object's type). + public string TypeId { get; set; } = ""; + /// Free-form identifier; defaults to "{GlobalId}_{TypeId}". + public string CustomId { get; set; } = ""; + /// Display name; defaults to "{TypeName}_{GlobalId}_{TypeId}". + public string Name { get; set; } = ""; } /// Shape primitive for object types. Procedural geometry is generated