implements PLN-0002 journey runtime model

This commit is contained in:
Nilton Constantino 2026-06-19 13:38:24 +01:00
parent aeb6236f5c
commit 7d9947e5f0
No known key found for this signature in database
12 changed files with 273 additions and 2 deletions

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c1fd63a9fe84c8fb09bb9c2e804ec8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71c2f06702924f18b413f79bb35f9af3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<JStage> stages = new();
public List<JEndpoint> endpoints = new();
public List<JConnection> connections = new();
public void EnsureDefaults()
{
stages ??= new List<JStage>();
endpoints ??= new List<JEndpoint>();
connections ??= new List<JConnection>();
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<JEndpoint> GetEndpointsForStage(string stageId)
{
EnsureDefaults();
var result = new List<JEndpoint>();
foreach (var endpoint in endpoints)
{
if (endpoint != null && endpoint.stageId == stageId)
{
result.Add(endpoint);
}
}
return result;
}
public List<JConnection> GetConnectionsForEndpoint(string endpointId)
{
EnsureDefaults();
var result = new List<JConnection>();
foreach (var connection in connections)
{
if (connection != null && connection.ContainsEndpoint(endpointId))
{
result.Add(connection);
}
}
return result;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fcb661d795ed4088af4ae73e4253f98b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<JWorldTile> occupiedTiles = new();
public List<string> tags = new();
public void EnsureDefaults()
{
occupiedTiles ??= new List<JWorldTile>();
tags ??= new List<string>();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dbe6985a3384e0190ac342eb49eb4d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fd7e60621d443e3a2f02fbb9ffcc801
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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":[]}

View File

@ -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