diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs b/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs new file mode 100644 index 0000000..b42e72a --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs @@ -0,0 +1,33 @@ +using System; + +namespace Intrepid.Gameplay.Journey +{ + [Serializable] + public sealed class JConnection + { + public string id; + public string endpointAId; + public string endpointBId; + public JConnectionDirectionality directionality = JConnectionDirectionality.Bidirectional; + + public bool ContainsEndpoint(string endpointId) + { + return endpointAId == endpointId || endpointBId == endpointId; + } + + public string GetOtherEndpointId(string endpointId) + { + if (endpointAId == endpointId) + { + return endpointBId; + } + + if (endpointBId == endpointId) + { + return endpointAId; + } + + return null; + } + } +} diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs.meta b/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs.meta new file mode 100644 index 0000000..b18a551 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JConnection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c1fd63a9fe84c8fb09bb9c2e804ec8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs b/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs new file mode 100644 index 0000000..8fb2a76 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs @@ -0,0 +1,21 @@ +using System; + +namespace Intrepid.Gameplay.Journey +{ + [Serializable] + public sealed class JEndpoint + { + public string id; + public string stageId; + public JWorldTile worldTile; + public JEndpointKind kind; + public bool required; + + // Used when kind is Socket. Ignored by Anchor and Lift endpoints. + public JSocketFace socketFace; + + public bool IsSocket => kind == JEndpointKind.Socket; + public bool IsAnchor => kind == JEndpointKind.Anchor; + public bool IsLift => kind == JEndpointKind.Lift; + } +} diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs.meta b/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs.meta new file mode 100644 index 0000000..4f3317d --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JEndpoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71c2f06702924f18b413f79bb35f9af3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs b/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs new file mode 100644 index 0000000..5353ed6 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace Intrepid.Gameplay.Journey +{ + [CreateAssetMenu(menuName = "GON/Journey/J Graph", fileName = "JGraph")] + public sealed class JGraphSO : ScriptableObject + { + public string sourceWorldLayoutId; + public string publishedAt; + public int schemaVersion = 1; + public string contentHash; + + public List stages = new(); + public List endpoints = new(); + public List connections = new(); + + public void EnsureDefaults() + { + stages ??= new List(); + endpoints ??= new List(); + connections ??= new List(); + + foreach (var stage in stages) + { + stage?.EnsureDefaults(); + } + } + + public JStage FindStage(string stageId) + { + EnsureDefaults(); + foreach (var stage in stages) + { + if (stage != null && stage.id == stageId) + { + return stage; + } + } + + return null; + } + + public JEndpoint FindEndpoint(string endpointId) + { + EnsureDefaults(); + foreach (var endpoint in endpoints) + { + if (endpoint != null && endpoint.id == endpointId) + { + return endpoint; + } + } + + return null; + } + + public JConnection FindConnection(string connectionId) + { + EnsureDefaults(); + foreach (var connection in connections) + { + if (connection != null && connection.id == connectionId) + { + return connection; + } + } + + return null; + } + + public List GetEndpointsForStage(string stageId) + { + EnsureDefaults(); + var result = new List(); + foreach (var endpoint in endpoints) + { + if (endpoint != null && endpoint.stageId == stageId) + { + result.Add(endpoint); + } + } + + return result; + } + + public List GetConnectionsForEndpoint(string endpointId) + { + EnsureDefaults(); + var result = new List(); + foreach (var connection in connections) + { + if (connection != null && connection.ContainsEndpoint(endpointId)) + { + result.Add(connection); + } + } + + return result; + } + } +} diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs.meta b/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs.meta new file mode 100644 index 0000000..b743025 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JGraphSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcb661d795ed4088af4ae73e4253f98b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs b/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs new file mode 100644 index 0000000..a1b4486 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; + +namespace Intrepid.Gameplay.Journey +{ + [Serializable] + public sealed class JStage + { + public string id; + public string displayName; + public int worldLayer; + public List occupiedTiles = new(); + public List tags = new(); + + public void EnsureDefaults() + { + occupiedTiles ??= new List(); + tags ??= new List(); + } + } +} diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs.meta b/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs.meta new file mode 100644 index 0000000..f4a5189 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JStage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5dbe6985a3384e0190ac342eb49eb4d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs b/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs new file mode 100644 index 0000000..d0e32fa --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs @@ -0,0 +1,39 @@ +using System; + +namespace Intrepid.Gameplay.Journey +{ + public enum JEndpointKind + { + Socket = 0, + Anchor = 1, + Lift = 2 + } + + public enum JSocketFace + { + North = 0, + South = 1, + East = 2, + West = 3 + } + + public enum JConnectionDirectionality + { + Bidirectional = 0, + AToB = 1, + BToA = 2 + } + + [Serializable] + public struct JWorldTile + { + public int x; + public int y; + + public JWorldTile(int x, int y) + { + this.x = x; + this.y = y; + } + } +} diff --git a/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs.meta b/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs.meta new file mode 100644 index 0000000..f73bca6 --- /dev/null +++ b/Assets/Scripts/Intrepid/Gameplay/Journey/JourneyTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fd7e60621d443e3a2f02fbb9ffcc801 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 98c5ad1..79bac2a 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,2 +1,2 @@ {"type":"meta","next_id":{"DSC":2,"AGD":2,"DEC":2,"PLN":5,"LSN":1,"CLSN":1}} -{"type":"discussion","id":"DSC-0001","status":"accepted","ticket":"world-editor-journey-spec","title":"World Editor / Journey Spec","created_at":"2026-06-19","updated_at":"2026-06-19","tags":["world-editor","journey","stage-contract","architecture"],"agendas":[{"id":"AGD-0001","file":"AGD-0001-world-editor-journey-spec.md","status":"accepted","created_at":"2026-06-19","updated_at":"2026-06-19"}],"decisions":[{"id":"DEC-0001","file":"DEC-0001-world-editor-journey-v1.md","status":"accepted","created_at":"2026-06-19","updated_at":"2026-06-19","ref_agenda":"AGD-0001"}],"plans":[{"id":"PLN-0001","file":"PLN-0001-world-journey-spec.md","status":"done","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0002","file":"PLN-0002-journey-runtime-model.md","status":"review","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0003","file":"PLN-0003-world-editor-authoring.md","status":"review","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0004","file":"PLN-0004-journey-commit-validation.md","status":"review","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0001","status":"accepted","ticket":"world-editor-journey-spec","title":"World Editor / Journey Spec","created_at":"2026-06-19","updated_at":"2026-06-19","tags":["world-editor","journey","stage-contract","architecture"],"agendas":[{"id":"AGD-0001","file":"AGD-0001-world-editor-journey-spec.md","status":"accepted","created_at":"2026-06-19","updated_at":"2026-06-19"}],"decisions":[{"id":"DEC-0001","file":"DEC-0001-world-editor-journey-v1.md","status":"accepted","created_at":"2026-06-19","updated_at":"2026-06-19","ref_agenda":"AGD-0001"}],"plans":[{"id":"PLN-0001","file":"PLN-0001-world-journey-spec.md","status":"done","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0002","file":"PLN-0002-journey-runtime-model.md","status":"done","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0003","file":"PLN-0003-world-editor-authoring.md","status":"review","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]},{"id":"PLN-0004","file":"PLN-0004-journey-commit-validation.md","status":"review","created_at":"2026-06-19","updated_at":"2026-06-19","ref_decisions":["DEC-0001"]}],"lessons":[]} diff --git a/discussion/workflow/plans/PLN-0002-journey-runtime-model.md b/discussion/workflow/plans/PLN-0002-journey-runtime-model.md index 2c7be2c..2f208ad 100644 --- a/discussion/workflow/plans/PLN-0002-journey-runtime-model.md +++ b/discussion/workflow/plans/PLN-0002-journey-runtime-model.md @@ -2,7 +2,7 @@ id: PLN-0002 ticket: world-editor-journey-spec title: Journey Runtime Model -status: review +status: done created: 2026-06-19 decisions: - DEC-0001