Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AI/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
- **Impact:** Lesson copy stays on the side panels; timing feedback looks like the level.
- **Refs:** `TutorialController.cs`, `TreeRhythmController.cs`, `Assets/Scenes/Tutorial.unity`

### Changed — Results QR link carries grade and score
- **Scope:** component:ResultScreen · integration
- **What:** The share link now encodes four params (`?start=…&placed=…&grade=…&score=…`). `TreeRunTracker.BuildViewerUrl` takes the final `Grade` and score, `TreeResultQrDisplay.PrepareResultQrCode` takes the run's `RhythmScoreTracker`, and both new query keys are editable on `TreeShareConfig`. Default viewer path moves from `/view` to `/results`.
- **Why:** The results web page needs the letter grade and numeric score from the link itself, not only the BST sequences.
- **Impact:** `PrepareResultQrCode` and `BuildViewerUrl` gained parameters; the result screen passes the score tracker it already displays. A missing tracker logs an error and shows the QR fallback instead of an incomplete link. Set `_viewerBaseUrl` per environment on the config asset.
- **Refs:** `TreeShareConfig.cs`, `TreeRunTracker.cs`, `TreeResultQrDisplay.cs`, `ResultScreenController.cs`, `TreeShareConfig.asset`

### Fixed — Player-side synthwave reacts to the song again in VS Bot / 2P
- **Scope:** component:PlayerVsBot
- **What:** `TwoPlayerGameCoordinator` now pulses P1's synthwave floor from P1 `OnBeat` (P2 already had this) and retargets the shared `AudioFFTAnalyzer` to P1's playing `AudioSource`. P2 `PlaySync` never starts a clip, so the analyzer had been listening to a silent source — hills stayed flat on the human side while the bot side still kicked from its beat wire.
Expand Down
17 changes: 15 additions & 2 deletions Assets/Integration/TreeResultQrDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ public void SetTracker(TreeRunTracker tracker)
* assigns it to the results-screen RawImage. Safe to call once per run;
* subsequent calls for the same run are no-ops until <see cref="ClearQr"/>.
* </summary>
* <param name="score">
* Same tracker the result screen displays; supplies the grade and total
* score encoded in the link.
* </param>
*/
public void PrepareResultQrCode()
public void PrepareResultQrCode(RhythmScoreTracker score)
{
if (_preparedForCurrentRun)
return;
Expand All @@ -72,6 +76,15 @@ public void PrepareResultQrCode()
return;
}

if (score == null)
{
Debug.LogError("[TreeResultQrDisplay] Missing RhythmScoreTracker — cannot encode grade and score.");
_tracker.FinishLevel();
ShowFallback();
_preparedForCurrentRun = true;
return;
}

if (_qrRawImage == null)
{
Debug.LogError("[TreeResultQrDisplay] Missing QR RawImage reference.");
Expand All @@ -81,7 +94,7 @@ public void PrepareResultQrCode()
}

_tracker.FinishLevel();
_lastUrl = _tracker.BuildViewerUrl();
_lastUrl = _tracker.BuildViewerUrl(score.CurrentGrade, score.TotalScore);
if (string.IsNullOrEmpty(_lastUrl))
{
Debug.LogError("[TreeResultQrDisplay] Viewer URL was empty (check TreeShareConfig).");
Expand Down
17 changes: 13 additions & 4 deletions Assets/Integration/TreeRunTracker.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;

/** <summary>
* Tracks one level run of BST construction for QR sharing.
*
* Holds the starting tree's original insertion order plus every value the
* player successfully places, in placement order. Used by
* <see cref="TreeResultQrDisplay"/> to build a seemytree viewer URL.
* <see cref="TreeResultQrDisplay"/> to build a results viewer URL of the form
* <c>?start=…&amp;placed=…&amp;grade=…&amp;score=…</c>.
*
* Attach beside <see cref="TreeRhythmController"/> on each GameController.
* Does not use DontDestroyOnLoad — lives for the GameScene level only.
Expand Down Expand Up @@ -123,12 +125,14 @@ public void ResetTracking()
}

/** <summary>
* Builds the seemytree viewer URL for the current run.
* Builds the results viewer URL for the current run.
* Empty placement lists are valid and encode as <c>placed=</c>.
* Base URL and query names come from <see cref="TreeShareConfig"/>.
* </summary>
* <param name="grade">Final letter grade shown on the result screen.</param>
* <param name="score">Final score from <see cref="RhythmScoreTracker.TotalScore"/>.</param>
*/
public string BuildViewerUrl()
public string BuildViewerUrl(Grade grade, long score)
{
if (_shareConfig == null)
{
Expand All @@ -141,12 +145,17 @@ public string BuildViewerUrl()

string startEncoded = Uri.EscapeDataString(startJoined);
string placedEncoded = Uri.EscapeDataString(placedJoined);
string gradeEncoded = Uri.EscapeDataString(grade.ToString());
string scoreEncoded = Uri.EscapeDataString(score.ToString(CultureInfo.InvariantCulture));

string baseUrl = _shareConfig.ViewerBaseUrl;
string startKey = _shareConfig.StartParamName;
string placedKey = _shareConfig.PlacedParamName;
string gradeKey = _shareConfig.GradeParamName;
string scoreKey = _shareConfig.ScoreParamName;

return $"{baseUrl}?{startKey}={startEncoded}&{placedKey}={placedEncoded}";
return $"{baseUrl}?{startKey}={startEncoded}&{placedKey}={placedEncoded}" +
$"&{gradeKey}={gradeEncoded}&{scoreKey}={scoreEncoded}";
}

#endregion
Expand Down
25 changes: 21 additions & 4 deletions Assets/Integration/TreeShareConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
[CreateAssetMenu(menuName = "Treeformance/TreeShareConfig", fileName = "TreeShareConfig")]
public class TreeShareConfig : ScriptableObject
{
/** <summary>Used when the asset leaves <c>_viewerBaseUrl</c> blank.</summary> */
private const string DefaultViewerBaseUrl = "https://seemytree.netlify.app/results";

[Header("Viewer")]
[Tooltip("Base URL for the tree viewer (no query string). Example: https://seemytree.netlify.app/view")]
[SerializeField] private string _viewerBaseUrl = "https://seemytree.netlify.app/view";
[Tooltip("Base URL for the results viewer (no query string). Example: https://seemytree.netlify.app/results")]
[SerializeField] private string _viewerBaseUrl = DefaultViewerBaseUrl;

[Header("Query Parameter Names")]
[Tooltip("Query key for the starting BST insertion order.")]
Expand All @@ -19,10 +22,16 @@ public class TreeShareConfig : ScriptableObject
[Tooltip("Query key for successful player placements in order.")]
[SerializeField] private string _placedParamName = "placed";

/** <summary>Host + path used before <c>?start=…&amp;placed=…</c>.</summary> */
[Tooltip("Query key for the final letter grade (SS, S, A, B, C, D, F).")]
[SerializeField] private string _gradeParamName = "grade";

[Tooltip("Query key for the final numeric score.")]
[SerializeField] private string _scoreParamName = "score";

/** <summary>Host + path used before <c>?start=…&amp;placed=…&amp;grade=…&amp;score=…</c>.</summary> */
public string ViewerBaseUrl =>
string.IsNullOrWhiteSpace(_viewerBaseUrl)
? "https://seemytree.netlify.app/view"
? DefaultViewerBaseUrl
: _viewerBaseUrl.TrimEnd('/');

/** <summary>Query parameter name for the starting insertion sequence.</summary> */
Expand All @@ -32,4 +41,12 @@ public class TreeShareConfig : ScriptableObject
/** <summary>Query parameter name for successful placements.</summary> */
public string PlacedParamName =>
string.IsNullOrWhiteSpace(_placedParamName) ? "placed" : _placedParamName;

/** <summary>Query parameter name for the final letter grade.</summary> */
public string GradeParamName =>
string.IsNullOrWhiteSpace(_gradeParamName) ? "grade" : _gradeParamName;

/** <summary>Query parameter name for the final numeric score.</summary> */
public string ScoreParamName =>
string.IsNullOrWhiteSpace(_scoreParamName) ? "score" : _scoreParamName;
}
4 changes: 3 additions & 1 deletion Assets/ScriptableObjects/Configs/TreeShareConfig.asset
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 12b30bbd212e049eb9d2fa93b78b1a36, type: 3}
m_Name: TreeShareConfig
m_EditorClassIdentifier:
_viewerBaseUrl: https://seemytree.netlify.app/view
_viewerBaseUrl: https://seemytree.netlify.app/results
_startParamName: start
_placedParamName: placed
_gradeParamName: grade
_scoreParamName: score
2 changes: 1 addition & 1 deletion Assets/UI/Style1/ResultScreenController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public async UniTask ShowAsync(RhythmScoreTracker score, IMenuInputProvider inpu
_treeQrDisplay = GetComponent<TreeResultQrDisplay>();
try
{
_treeQrDisplay?.PrepareResultQrCode();
_treeQrDisplay?.PrepareResultQrCode(score);
}
catch (Exception ex)
{
Expand Down