---
id: PLN-0002
ticket: world-editor-journey-spec
title: Journey Runtime Model
status: done
created: 2026-06-19
decisions:
  - DEC-0001
tags:
  - runtime
  - journey
  - scriptableobject
---

## Briefing

Implement the runtime Journey data model consumed by gameplay. This plan creates runtime-safe types under `Assets/Scripts/Intrepid/Gameplay/Journey` and keeps them independent from editor-only code.

## Source Decisions

- `DEC-0001`: World Editor / Journey V1.

## Target

Create the runtime Journey model:

- `JGraphSO`
- `JStage`
- `JEndpoint`
- `JEndpointSocket`
- `JEndpointAnchor`
- `JEndpointLift`
- `JConnection`
- supporting enums/value types for endpoint kind, directionality, world tile coordinates, socket face, and validation metadata when needed.

## Scope

- Runtime serializable data only.
- ScriptableObject asset type for `JGraphSO`.
- Stable GUID/string ids for `JStage`, `JEndpoint`, and `JConnection`.
- Publication metadata on `JGraphSO`.
- Query helpers that do not depend on `UnityEditor`.

## Out Of Scope

- World Editor UI.
- Commit/publish pipeline.
- Stage scene generation.
- Stage Editor bake.
- Loading hints.
- Concrete `JRequirement` structure.
- Runtime destination selection UI for multi-anchor connections.

## Execution Plan

1. Create runtime folder structure.
   - Target `Assets/Scripts/Intrepid/Gameplay/Journey`.
   - Preserve existing `.meta` files if Unity already created the folder.

2. Add `JGraphSO`.
   - Implement as a `ScriptableObject`.
   - Fields: `sourceWorldLayoutId`, `publishedAt`, `schemaVersion`, optional `contentHash`, `List<JStage>`, `List<JEndpoint>`, `List<JConnection>`.
   - Add read-only query methods for stages, endpoints, and connections by id.
   - Do not reference `UnityEditor`.

3. Add `JStage`.
   - Serializable runtime logical Stage record.
   - Fields: stable id, display/name field, world layer, occupied world tiles, optional tag references if compatible with existing tag conventions.
   - Do not include Stage scene generation or Stage bake data.

4. Add endpoint model.
   - Use a serializable base record or discriminated model that Unity can serialize reliably.
   - Include stable id, owning `JStage` id, world tile coordinate, endpoint kind, required flag, and type-specific data.
   - Socket data includes face.
   - Anchor data supports multiple connections by model validation, not by embedded scene interaction logic.
   - Lift data includes vertical alignment requirements by world tile coordinate and distinct world layer.

5. Add `JConnection`.
   - Fields: stable id, endpoint A id, endpoint B id, directionality.
   - Keep extensibility for future requirements without implementing a concrete requirement system in V1.
   - Do not add loading hints in V1.

6. Add query helpers.
   - Connections for endpoint id.
   - Endpoints for stage id.
   - Stage lookup by id.
   - Optional lightweight validation-facing helpers without editor dependencies.

## Acceptance Criteria

- Runtime Journey files live under `Assets/Scripts/Intrepid/Gameplay/Journey`.
- No runtime Journey file imports `UnityEditor`.
- Journey runtime ScriptableObject is named `JGraphSO`.
- Runtime Journey element names use prefix `J`.
- `JGraphSO` contains publication metadata required by `DEC-0001`.
- `JStage`, `JEndpoint`, and `JConnection` use stable GUID/string ids.
- Loading hints and concrete requirements are not implemented as V1 commitments.

## Validation

- Unity compile succeeds.
- Search `Assets/Scripts/Intrepid/Gameplay/Journey` for `UnityEditor`; it must return no runtime dependency.
- Create a temporary `JGraphSO` asset in Unity and verify its serialized fields are visible and persist.
- No automated tests are required for this phase.

## Risks

- Unity serialization may not handle polymorphic endpoint classes as desired without `[SerializeReference]`; choose a serialization pattern consistent with the Unity version and repository style.
- Existing tag APIs may be runtime-safe but should not be forced into V1 if they complicate serialization.
- Overbuilding query APIs could harden runtime behavior that is intentionally out of scope.
