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
I propose a lightweight, code-first Component Extension System for the Untold Editor. The editor will run macOS-only for now, while a separate visionOS Remote Display app will mirror rendering output and forward input to the macOS editor. Because visionOS (like other Apple App Stores) prohibits dynamic native code loading, the extension mechanism resides entirely on macOS. Extensions are authored as Swift/SwiftPM/Xcode modules, compiled and loaded by the macOS editor. The visionOS app renders frames streamed from macOS and relays input; it does not load third-party code.
At the core, we use Swift compiler plugins + macros to mark component properties for in-editor editing and hot binding without boilerplate (e.g., @EditorFloat, @EditorEnum). The compiler plugin emits machine-readable metadata that the editor ingests to auto-build UI controls and runtime bindings.
Goals & Non-Goals
Goals
G1: macOS-only Editor (initially) with remote rendering to visionOS via a companion app that mirrors output and forwards input.
G2: Bring back component extensions with a simple, declarative authoring model (attribute-driven).
G3:Zero extra glue code: annotations generate metadata + bindings automatically.
G4: Support loading project code (components) from Xcode/SPM builds directly into the editor on macOS.
G5: Maintain parity with the pre-split component system for runtime semantics.
Non-Goals (Phase 1)
N1: Native code extensions on visionOS.
N2: Scripting-VM performance work (beyond basic console tooling).
N3: On-device compilation for visionOS.
N4: Network multi-user co-editing.
Platform Architecture Overview
macOS Editor (authoritative)
Hosts the scene graph, asset pipeline, and component extension loader.
Compiles/links project code (SPM/Xcode).
Provides the Editor Service (IPC/WebSocket/QUIC) that the remote display uses.
visionOS Remote Display (companion app)
No dynamic code loading.
Receives streamed render frames (or GPU textures) from the macOS Editor.
Forwards input (gaze/hand gestures/taps/keyboard) back to macOS Editor.
Optional lightweight tooling overlays (HUDs) driven entirely by editor-pushed metadata.
Color uses native macOS color well + HDR support when available.
Backwards Compatibility
Legacy components (pre-split) remain valid; if no macros are found, fields can be surfaced via a compat shim (manual registry or default reflection) to preserve prior behavior.
Build, Load, and Project Integration
Xcode/SPM Layout
Components live in one or more SPM targets or Xcode subprojects within the main game/app workspace.
The Editor Plugin is added as a build dependency for those targets to emit *.editor.json and optional registries.
The Editor Host app watches the build folder (DerivedData or a configured Products/) for updated artifacts.
Loading Strategy (macOS)
Compile components as .dylib or .bundle with stable ABI entry points (e.g., unbtols_component_init()).
On editor start or project (re)build, the editor loads bundles dynamically.
Code signing is required for hardened runtime; local development uses developer-signed artifacts.
Serialization
Scene and prefab files store component types + field values.
A schema version accompanies metadata; the editor migrates data if fields are renamed or types change.
Remote Rendering for visionOS
Constraints & Rationale
visionOS App Store disallows dynamic native code loading; scripting is allowed but too slow for our use case.
Therefore, all third-party/native extensions run on macOS.
visionOS app is a remote viewer + input forwarder.
Link & Transport
Preferred: QUIC or WebRTC for low-latency bi-directional transport (NAT-friendly).
Latency Targets
Motion-to-photon: ≤ 40–60 ms (LAN), with frame pacing from the Editor.
Adaptive bitrate and resolution scaling based on link quality.
Tooling Overlays
HUD overlays are editor-driven, described via a tiny UI schema (buttons, sliders, pickers) pushed to the client; the client never executes extension code.
Security, Signing, and Stability
macOS only dynamic loading; visionOS app contains no untrusted code.
Enforce codesigning for bundles; optionally require a developer team ID allowlist.
Sandboxed IPC with strict message schemas.
Crash isolation: load extensions into a helper process with XPC; hot-reload by restarting helper without killing the editor.
Example: End-to-End Developer Flow
Create MyGameplayComponents SPM target.
Add dependency on UnbtolsEditorPlugin and import EditorMacros.
Annotate fields with @Editor* macros.
Build project in Xcode → plugin emits MyGameplayComponents.editor.json and registry.
Open project in Editor → dynamic load of MyGameplayComponents.bundle → inspector auto-populates.
Open visionOS Remote Display → see live scene, tweak properties in macOS editor; changes visible instantly in the headset.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I propose a lightweight, code-first Component Extension System for the Untold Editor. The editor will run macOS-only for now, while a separate visionOS Remote Display app will mirror rendering output and forward input to the macOS editor. Because visionOS (like other Apple App Stores) prohibits dynamic native code loading, the extension mechanism resides entirely on macOS. Extensions are authored as Swift/SwiftPM/Xcode modules, compiled and loaded by the macOS editor. The visionOS app renders frames streamed from macOS and relays input; it does not load third-party code.
At the core, we use Swift compiler plugins + macros to mark component properties for in-editor editing and hot binding without boilerplate (e.g.,
@EditorFloat,@EditorEnum). The compiler plugin emits machine-readable metadata that the editor ingests to auto-build UI controls and runtime bindings.Goals & Non-Goals
Goals
Non-Goals (Phase 1)
Platform Architecture Overview
macOS Editor (authoritative)
visionOS Remote Display (companion app)
Data Flow
Component Extension System Design
Authoring Model (Macros/Attributes)
Developers annotate Swift component properties with editor-aware macros:
Supported macros (initial set):
@EditorFloat(min:max:step:)@EditorInt(min:max:step:)@EditorBool@EditorColor@EditorEnum(options:default:)@EditorVector2/3/4@EditorQuat@EditorAsset(type:)(e.g., texture, mesh)@EditorGroup("Lighting")/@EditorCategory("Rendering")@EditorHidden(exposed in metadata but hidden in default UI)Compiler Plugin Responsibilities
We use Swift Compiler Plugins + SwiftSyntax to:
<TargetName>.editor.json(or swift static registry) describing components, fields, types, attributes, constraints, and default values.Example metadata (excerpt):
{ "components": [ { "type": "SunLightComponent", "displayName": "Sun Light", "fields": [ { "name": "intensity", "kind": "float", "min": 0.0, "max": 100000.0, "step": 10, "default": 10000 }, { "name": "color", "kind": "color", "default": [1,1,1] }, { "name": "type", "kind": "enum", "options": ["Directional","Point","Spot"], "default": "Directional" }, { "name": "castsShadows", "kind": "bool", "default": true } ] } ] }Editor Runtime (Binding Layer)
*.editor.json(or a compiled registry symbol), merges them, and auto-builds inspector UI.UI Generation
@EditorGroup/@EditorCategorydrive tabs/sections.Backwards Compatibility
Build, Load, and Project Integration
Xcode/SPM Layout
*.editor.jsonand optional registries.Products/) for updated artifacts.Loading Strategy (macOS)
unbtols_component_init()).Serialization
Remote Rendering for visionOS
Constraints & Rationale
Link & Transport
Latency Targets
Tooling Overlays
Security, Signing, and Stability
Example: End-to-End Developer Flow
MyGameplayComponentsSPM target.UnbtolsEditorPluginand importEditorMacros.@Editor*macros.MyGameplayComponents.editor.jsonand registry.MyGameplayComponents.bundle→ inspector auto-populates.Public API (Draft)
Macros
Registry & Hooks
Migration from Pre-Split System
Minimal Working Example
Beta Was this translation helpful? Give feedback.
All reactions