Feature/lanes #40

Merged
dutchie031 merged 12 commits from feature/lanes into develop 2026-09-07 17:08:27 +00:00
5 changed files with 677 additions and 11 deletions
Showing only changes of commit 368310d026 - Show all commits
Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

+2 -1
View File
@@ -19,9 +19,10 @@ class Header extends HTMLElement {
<div class="dropdown-content">
<a href="/pages/include-script.html">Include the Script</a>
<a href="/pages/first-start.html">First Start</a>
<a href="/pages/advanced/map-markings.html">Map Markings</a>
<a href="/pages/advanced/CAP.html">Advanced: CAP</a>
<a href="/pages/advanced/missions.html">Advanced: Missions</a>
<a href="/pages/advanced/map-markings.html">Map Markings</a>
<a href="/pages/advanced/lanes.html">Advanced: Lanes</a>
</div>
</div>
+125
View File
@@ -0,0 +1,125 @@
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Spearhead Lanes</title>
<link rel="stylesheet" href="/style/style.css">
<script src="/js/site.js"></script>
<style>
.side-nav a.active {
font-weight: bold;
color: #4fc3f7;
}
</style>
<script type="module" src="/js/components.js"></script>
</head>
<body>
<header>
<app-header></app-header>
</header>
<main>
<div class="reference-container">
<app-sidebar></app-sidebar>
<div class="content-wrapper">
<h1>Lanes</h1>
<p>
If up to now you've used mission stages like <code-inline>MISSIONSTAGE_1_STAGE</code-inline> you've been using the main lane. <br>
This is the default or "main" lane, however, if you wanted to mix things up and create a more dynamic mission, you can use additional lanes. <br>
Each lane can have its own set of mission stages, allowing for parallel or branching mission objectives.
</p>
<h2 id="how-it-works">How To</h2>
<h3 id="define-lanes">Define Lanes</h3>
<p>
Lanes are defined implicitly in the naming convention of the <code-inline>MISSIONSTAGE_</code-inline>. <br>
A lane is identified by a single character (alpha [A-Z]), which gives you 26 unique lanes. <br>
For example, <code-inline>MISSIONSTAGE_A1_[name]</code-inline> would belong to lane A. <br>
<br>
If there is no lane character specified, the stage belongs to the main lane. <br>
<br>
The 26 lane limit is only relevant if you want 26 lanes at the same time. <br>
But splitting up lanes (eg. (1-4 and 10-15) ) you can easily have more than 26 stages throughout your entire mission. <br>
<br>
Lanes don't have to start at index 1. as in the example lanes can easily start at any index. <br>
How lanes are then activated and activate other lanes is described below in the Dependencies Explained part.
</p>
<h3 id="dependencies">Dependencies Explained</h3>
<p>
When we are talking about lanes it's important to make the distinction between the main lane and additional lanes. <br>
The main lane is not only the default, but it's also the central lane that other lanes depend on. <br>
<h4>Chapters</h4>
Another term that we have used in the code is `Chapter` which refers to a grouping of mission stages within a lane. <br>
These are implied and cannot be directly controlled or altered. <br>
A chapter is a set of `MissionStage`s that are directly connected. <br>
For `MissionStages` `[ A1, A2, A3, A5, A6]` there are 2 chapters: `[ A1, A2, A3]` and `[ A5, A6]`. <br>
Within a chapter the stages are only directly dependent on each other. Meaning A2 will start when A1 is completed. <br>
<br>
However, the chapter start is where the inter-lane dependencies come into play. <br>
These operate a little differently. <br>
<br>
In the Visual example you can see the Stages grouped into chapters by the red boxes. <br>
<h4>Side Lane Chapter start</h4>
<p>
Side lane chapters are started when all are true:
<ul>
<li>The main lane is at or above the current stage lane number.</li>
<li>All previous chapters in the same side lane have been completed.</li>
</ul>
</p>
<h4>Main Lane Chapter start</h4>
<p>
Main lane chapters are started when all are true:
<ul>
<li>The previous chapter in the main lane has been completed.</li>
<li>All side lanes are at or above the current stage lane number or the side lane has no additional stages.</li>
</ul>
</p>
</p>
<h2 id="visual">Visual</h2>
<p>
The image below illustrates how different lanes can be used within a mission. <br>
In the example you can see how the dependency between the main lane and side lanes works. <br>
An arrow means that the completion of one stage is required before the next stage can begin.
</p>
<img src="/img/lanes.png" alt="Example of mission lanes">
<h2 id="mermaid">Mermaid</h2>
<p>
Spearhead automatically exports a spearhead diagram to the logs on starting a mission. <br>
This can be handy to visualize the logic and lanes you've created and verify your mission flow will be the way you want it. <br>
</p>
<h3 id="mermaid-log-example">Log Example</h3>
<p> TODO: Show log example</p>
dutchie031 marked this conversation as resolved Outdated
Outdated
Review

TODOs

TODOs
<h3 id="mermaid-diagram-example">Diagram Example</h3>
<p> TODO: Show diagram example</p>
<h2 id="lane-limitations">Limitations</h2>
<h3 class="lane-limitations-cap">CAP</h3>
<p>
Due to the CAP naming conventions, we've opted to currently have CAP only react with the main lane. <br>
This might mean a bit less flexibility when using lanes for major mission logic, however, it's a limitation we've accepted for now. <br>
In the future we might be able to extend CAP's interaction with other lanes as well. <br>
Currently <a href="https://git.dutchie031.com/Spearhead/spearhead/issues/47">this issue</a> can be tracked here.
</p>
</div>
</div>
</main>
<footer>
<p>&copy; 2025 Spearhead Project</p>
</footer>
</body>
</html>
+1 -2
View File
@@ -262,7 +262,7 @@ header nav a:hover::after {
overflow: hidden;
top: 100%; /* Position below the dropdown */
left: 0; /* Align left edge */
min-width: 160px;
min-width: 240px;
background-color: var(--color-bg-secondary);
box-shadow: var(--shadow-medium);
@@ -336,7 +336,6 @@ main {
}
.side-nav {
width: 200px;
min-width: 200px;
padding-left: 0;
overflow-y: auto;
+549 -8
View File
@@ -1,7 +1,7 @@
{
"type": "excalidraw",
"version": 2,
"source": "vscode-webview://1hn2vaam3v69jt67pr4i27hnkafotvd70l4ao9nlb18pmrffl5dm",
"source": "vscode-webview://1h45nhtr1vhnknf2q5n6qdd43citnkfueml5qdvamifv7pfv0our",
"elements": [
{
"id": "kJXWwZE94uUnPMEB7mBNj",
@@ -629,11 +629,11 @@
"type": 2
},
"seed": 2125327475,
"version": 40,
"versionNonce": 1013087493,
"version": 44,
"versionNonce": 2047370396,
"isDeleted": true,
"boundElements": [],
"updated": 1787675736572,
"updated": 1788258273370,
"link": null,
"locked": false,
"points": [
@@ -2138,7 +2138,7 @@
"version": 99,
"versionNonce": 1709724811,
"isDeleted": false,
"boundElements": null,
"boundElements": [],
"updated": 1787675780472,
"link": null,
"locked": false,
@@ -2263,7 +2263,7 @@
"version": 3,
"versionNonce": 1276059851,
"isDeleted": true,
"boundElements": null,
"boundElements": [],
"updated": 1787675789610,
"link": null,
"locked": false,
@@ -2302,7 +2302,7 @@
"version": 261,
"versionNonce": 1283832069,
"isDeleted": true,
"boundElements": null,
"boundElements": [],
"updated": 1787675799132,
"link": null,
"locked": false,
@@ -2357,7 +2357,7 @@
"version": 382,
"versionNonce": 2105101093,
"isDeleted": false,
"boundElements": null,
"boundElements": [],
"updated": 1787675810843,
"link": null,
"locked": false,
@@ -2398,6 +2398,547 @@
"startArrowhead": null,
"endArrowhead": "arrow",
"elbowed": false
},
{
"id": "Qg114yJFcnUOPX16ZsJ8x",
"type": "rectangle",
"x": 509.8671875,
"y": 686.59375,
"width": 444.67578125,
"height": 167.3125,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"VfG5-6eCT8RzeqEVN8myu"
],
"frameId": null,
"index": "ap",
"roundness": {
"type": 3
},
"seed": 1685903900,
"version": 112,
"versionNonce": 1755199388,
"isDeleted": false,
"boundElements": null,
"updated": 1788258305636,
"link": null,
"locked": false
},
{
"id": "73h7FwfangZc2to491dHS",
"type": "text",
"x": 528.00390625,
"y": 660.9140625,
"width": 84.21994018554688,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"VfG5-6eCT8RzeqEVN8myu"
],
"frameId": null,
"index": "aq",
"roundness": null,
"seed": 2008726428,
"version": 28,
"versionNonce": 557293604,
"isDeleted": false,
"boundElements": null,
"updated": 1788258305636,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "DGkXXz8b3r1CA3lp1SUNA",
"type": "rectangle",
"x": 1072.755859375,
"y": 843.8359375,
"width": 444.67578125,
"height": 167.3125,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"Wu4PaRDsQhtHo9txEwFaq"
],
"frameId": null,
"index": "ar",
"roundness": {
"type": 3
},
"seed": 81759516,
"version": 274,
"versionNonce": 1049204252,
"isDeleted": false,
"boundElements": [],
"updated": 1788258312611,
"link": null,
"locked": false
},
{
"id": "gHZ2EHWic_RFDVzfaEeWl",
"type": "text",
"x": 1090.892578125,
"y": 818.15625,
"width": 84.21994018554688,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"Wu4PaRDsQhtHo9txEwFaq"
],
"frameId": null,
"index": "as",
"roundness": null,
"seed": 1814530460,
"version": 190,
"versionNonce": 1437102748,
"isDeleted": false,
"boundElements": [],
"updated": 1788258312611,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "yzc8kTihzHlUVl-TDoGtD",
"type": "rectangle",
"x": 507.05134802628254,
"y": 1027.3553987485943,
"width": 779.734375,
"height": 180.99004003531365,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dPJ-abW3oM5fQQd-eQqzv"
],
"frameId": null,
"index": "at",
"roundness": {
"type": 3
},
"seed": 607103004,
"version": 711,
"versionNonce": 2046521372,
"isDeleted": false,
"boundElements": [],
"updated": 1788258356226,
"link": null,
"locked": false
},
{
"id": "Sw0whVPXyycRuB36rl13U",
"type": "text",
"x": 892.9185355262825,
"y": 1105.350418766251,
"width": 8,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dPJ-abW3oM5fQQd-eQqzv"
],
"frameId": null,
"index": "atG",
"roundness": null,
"seed": 257763356,
"version": 7,
"versionNonce": 969870492,
"isDeleted": true,
"boundElements": null,
"updated": 1788258356227,
"link": null,
"locked": false,
"text": "",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "center",
"verticalAlign": "middle",
"containerId": "yzc8kTihzHlUVl-TDoGtD",
"originalText": "",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "ePG9RXnjdF7K-5HCGF-sG",
"type": "text",
"x": 892.826171875,
"y": 1105.350418766251,
"width": 8,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dPJ-abW3oM5fQQd-eQqzv"
],
"frameId": null,
"index": "atV",
"roundness": null,
"seed": 1253487140,
"version": 3,
"versionNonce": 1886913564,
"isDeleted": true,
"boundElements": null,
"updated": 1788258344772,
"link": null,
"locked": false,
"text": "",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "center",
"verticalAlign": "middle",
"containerId": "yzc8kTihzHlUVl-TDoGtD",
"originalText": "",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "R_Kw8DfCduiWxP7CASb_N",
"type": "text",
"x": 524.3895472712409,
"y": 998.6389362160919,
"width": 91.1047910105572,
"height": 27.04371162275886,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dPJ-abW3oM5fQQd-eQqzv"
],
"frameId": null,
"index": "au",
"roundness": null,
"seed": 12338332,
"version": 420,
"versionNonce": 1541295132,
"isDeleted": false,
"boundElements": [],
"updated": 1788258353639,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 21.63496929820709,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "7ToWvccfEZqbEAjYL4emv",
"type": "text",
"x": 831,
"y": 1209,
"width": 8,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"index": "av",
"roundness": null,
"seed": 1688532764,
"version": 3,
"versionNonce": 1539555236,
"isDeleted": true,
"boundElements": null,
"updated": 1788258343223,
"link": null,
"locked": false,
"text": "",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "9skEFGeqqszPFdJV66133",
"type": "rectangle",
"x": 1330.6578165538313,
"y": 667.0195187552217,
"width": 444.67578125,
"height": 167.3125,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dousqSQWhbh19Dj8kK4fS"
],
"frameId": null,
"index": "aw",
"roundness": {
"type": 3
},
"seed": 853836316,
"version": 170,
"versionNonce": 1121900188,
"isDeleted": false,
"boundElements": [],
"updated": 1788258361087,
"link": null,
"locked": false
},
{
"id": "4Cd9i97bkeod6ywtcj5Xn",
"type": "text",
"x": 1348.7945353038313,
"y": 641.3398312552217,
"width": 84.21994018554688,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"dousqSQWhbh19Dj8kK4fS"
],
"frameId": null,
"index": "ax",
"roundness": null,
"seed": 1472585372,
"version": 86,
"versionNonce": 243376924,
"isDeleted": false,
"boundElements": [],
"updated": 1788258361087,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "U8a4GgGtIoLS6pXwncq5a",
"type": "rectangle",
"x": 1810.8701028484863,
"y": 843.8080905841363,
"width": 230.73755409848874,
"height": 167.3125,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"IWb0wwURCie1t66j-aH-H"
],
"frameId": null,
"index": "ay",
"roundness": {
"type": 3
},
"seed": 1566757796,
"version": 308,
"versionNonce": 1300628124,
"isDeleted": false,
"boundElements": [],
"updated": 1788258382644,
"link": null,
"locked": false
},
{
"id": "YB4-1BJixVvFCAPEKUjkb",
"type": "text",
"x": 1829.0068215984863,
"y": 818.1284030841363,
"width": 84.21994018554688,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"IWb0wwURCie1t66j-aH-H"
],
"frameId": null,
"index": "az",
"roundness": null,
"seed": 1754316580,
"version": 184,
"versionNonce": 1187836068,
"isDeleted": false,
"boundElements": [],
"updated": 1788258367320,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
},
{
"id": "BbFtWqq47jrAmSsK1kS5K",
"type": "rectangle",
"x": 1572.2560817430196,
"y": 1164.5515767881157,
"width": 213.3201668995678,
"height": 167.3125,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"Y2e1HJZ6fg1eVldte5E0E"
],
"frameId": null,
"index": "b00",
"roundness": {
"type": 3
},
"seed": 1408083100,
"version": 307,
"versionNonce": 1993713316,
"isDeleted": false,
"boundElements": [],
"updated": 1788258378727,
"link": null,
"locked": false
},
{
"id": "8ysTWPdFv_xsWQSdnrBNI",
"type": "text",
"x": 1590.3928004930196,
"y": 1138.8718892881157,
"width": 84.21994018554688,
"height": 25,
"angle": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [
"Y2e1HJZ6fg1eVldte5E0E"
],
"frameId": null,
"index": "b01",
"roundness": null,
"seed": 1887875356,
"version": 138,
"versionNonce": 336624028,
"isDeleted": false,
"boundElements": [],
"updated": 1788258371803,
"link": null,
"locked": false,
"text": "Chapter ",
"fontSize": 20,
"fontFamily": 5,
"textAlign": "left",
"verticalAlign": "top",
"containerId": null,
"originalText": "Chapter ",
"autoResize": true,
"lineHeight": 1.25
}
],
"appState": {