From 72ccd0bc3312fe130d1b6a160a81bf300fe01a04 Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:42:15 +0000 Subject: [PATCH 01/14] start to convert starseek save data to csv --- .../AstroBalance/Assets/Scripts/GameData.cs | 60 +++++++++++++++++++ .../AstroBalance/Assets/Scripts/SaveData.cs | 43 +++++++++++-- .../Assets/Scripts/StarSeek/StarSeekData.cs | 7 +++ 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/GameData.cs b/projects/AstroBalance/Assets/Scripts/GameData.cs index 14afc2f1..ffb48c41 100644 --- a/projects/AstroBalance/Assets/Scripts/GameData.cs +++ b/projects/AstroBalance/Assets/Scripts/GameData.cs @@ -1,4 +1,7 @@ using System; +using System.Linq; +using System.Reflection; +using System.Text; /// /// Base class for a single game's save data. @@ -22,4 +25,61 @@ public void LogEndTime() { endTime = DateTime.Now.ToString("HH:mm:ss"); } + + private FieldInfo[] GetFields() + { + Type type = this.GetType(); + FieldInfo[] fields = type.GetFields(); + FieldInfo[] sortedFields = new FieldInfo[fields.Length]; + + // To ensure they are always returned in the same order, + // let's sort the fields. + // We return date, startTime, endTime, gameCompleted first (as this is general data + // for all games, and useful to have at the start of the csv) + // then any other fields in alphabetical order + sortedFields[0] = type.GetField("date"); + sortedFields[1] = type.GetField("startTime"); + sortedFields[2] = type.GetField("endTime"); + sortedFields[3] = type.GetField("gameCompleted"); + + Array.Sort(fields, (x, y) => String.Compare(x.Name, y.Name)); + + return fields; + } + + public virtual string ToCsvHeader() + { + StringBuilder header = new StringBuilder(); + FieldInfo[] fields = GetFields(); + + for (int i = 0; i < fields.Length; i++) + { + header.Append(fields[i].Name); + if (i < fields.Length - 1) + { + header.Append(","); + } + } + return header.ToString(); + + return "date,startTime,endTime,gameCompleted"; + } + + public virtual string ToCsvRow() + { + StringBuilder row = new StringBuilder(); + FieldInfo[] fields = GetFields(); + + for (int i = 0; i < fields.Length; i++) + { + row.Append(fields[i].GetValue(this)); + if (i < fields.Length - 1) + { + row.Append(","); + } + } + return row.ToString(); + + return $"{date},{startTime},{endTime},{gameCompleted}"; + } } diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index d51c487f..57537e52 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using NUnit.Framework.Constraints; +using UnityEditor.Experimental.GraphView; using UnityEngine; /// @@ -11,6 +13,7 @@ public class SaveData where T : GameData { + public bool saveFileExists = false; public List savedGames = new List(); private string dataPath; @@ -22,9 +25,8 @@ public class SaveData public SaveData(string filename) { // currently defaults to "C:\Users\username\AppData\LocalLow\DefaultCompany\AstroBalance" on Windows - dataPath = Path.Combine(Application.persistentDataPath, filename + ".json"); - - Load(); + dataPath = Path.Combine(Application.persistentDataPath, filename + ".csv"); + CheckSaveFileExists(); } /// @@ -33,8 +35,27 @@ public SaveData(string filename) /// Game data from this session public void SaveGameData(T gameData) { - savedGames.Add(gameData); - Save(); + using (StreamWriter sw = new StreamWriter(dataPath, true)) + { + if (!saveFileExists) + { + sw.WriteLine(gameData.ToCsvHeader()); + saveFileExists = true; + } + + sw.WriteLine(gameData.ToCsvRow()); + } + + //if (File.Exists(dataPath)) + //{ + + //} + //else + //{ + + //} + // savedGames.Add(gameData); + //Save(); } /// @@ -60,6 +81,18 @@ public void Save() File.WriteAllText(dataPath, json); } + private void CheckSaveFileExists() + { + if (File.Exists(dataPath)) + { + saveFileExists = true; + } + else + { + saveFileExists = false; + } + } + /// /// Load data about previous games from file (if any). /// diff --git a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs index 2191334a..c6b5be62 100644 --- a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs @@ -6,4 +6,11 @@ public class StarSeekData : GameData { public int timeLimitSeconds; public int nStarsCollected; + + //public override string ToCsvHeader() + //{ + // string csvHeader = base.ToCsvHeader(); + // csvHeader += "timeLimitSeconds,nStarsCollected"; + // return csvHeader; + //} } From a305ea050ea0f809fa4e6bbb04e2ab99d074f019 Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Tue, 10 Feb 2026 09:55:32 +0000 Subject: [PATCH 02/14] Sort saved fields, so they are always returned in the same order --- .../AstroBalance/Assets/Scripts/GameData.cs | 24 +++++++++---- .../Scripts/RocketLaunch/LaunchControl.cs | 2 +- .../AstroBalance/Assets/Scripts/SaveData.cs | 34 ++++++++----------- .../StarCollector/StarCollectorManager.cs | 2 +- .../Assets/Scripts/StarMap/StarMapManager.cs | 2 +- .../Scripts/StarSeek/StarSeekManager.cs | 4 ++- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/GameData.cs b/projects/AstroBalance/Assets/Scripts/GameData.cs index ffb48c41..4a30477f 100644 --- a/projects/AstroBalance/Assets/Scripts/GameData.cs +++ b/projects/AstroBalance/Assets/Scripts/GameData.cs @@ -26,6 +26,11 @@ public void LogEndTime() endTime = DateTime.Now.ToString("HH:mm:ss"); } + /// + /// Return info on all public fields. + /// Order is: date, startTime, endTime, gameCompleted, then any + /// other fields in alphabetical order. + /// private FieldInfo[] GetFields() { Type type = this.GetType(); @@ -34,17 +39,28 @@ private FieldInfo[] GetFields() // To ensure they are always returned in the same order, // let's sort the fields. + // We return date, startTime, endTime, gameCompleted first (as this is general data // for all games, and useful to have at the start of the csv) - // then any other fields in alphabetical order sortedFields[0] = type.GetField("date"); sortedFields[1] = type.GetField("startTime"); sortedFields[2] = type.GetField("endTime"); sortedFields[3] = type.GetField("gameCompleted"); + // Then, all other fields sorted in alphabetical order Array.Sort(fields, (x, y) => String.Compare(x.Name, y.Name)); - return fields; + int nextIndex = 4; + foreach (FieldInfo field in fields) + { + if (!sortedFields.Contains(field)) + { + sortedFields[nextIndex] = field; + nextIndex++; + } + } + + return sortedFields; } public virtual string ToCsvHeader() @@ -61,8 +77,6 @@ public virtual string ToCsvHeader() } } return header.ToString(); - - return "date,startTime,endTime,gameCompleted"; } public virtual string ToCsvRow() @@ -79,7 +93,5 @@ public virtual string ToCsvRow() } } return row.ToString(); - - return $"{date},{startTime},{endTime},{gameCompleted}"; } } diff --git a/projects/AstroBalance/Assets/Scripts/RocketLaunch/LaunchControl.cs b/projects/AstroBalance/Assets/Scripts/RocketLaunch/LaunchControl.cs index bb78863a..1a2cbe1b 100644 --- a/projects/AstroBalance/Assets/Scripts/RocketLaunch/LaunchControl.cs +++ b/projects/AstroBalance/Assets/Scripts/RocketLaunch/LaunchControl.cs @@ -64,7 +64,7 @@ void Start() headPoseBuffer = new HeadPoseBuffer(headPoseBufferCapacity); SaveData saveData = new(saveFilename); - RocketLaunchData lastGameData = saveData.GetLastGameData(); + RocketLaunchData lastGameData = saveData.GetLastCompleteGameData(); if (lastGameData == null) { diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 57537e52..618bcfab 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -45,41 +45,35 @@ public void SaveGameData(T gameData) sw.WriteLine(gameData.ToCsvRow()); } - - //if (File.Exists(dataPath)) - //{ - - //} - //else - //{ - - //} - // savedGames.Add(gameData); - //Save(); } /// - /// Get data from the last played game session. + /// Get data from the last complete played game session. /// - public T GetLastGameData() + public T GetLastCompleteGameData() { + if (!saveFileExists) + { + return null; + } + return savedGames.LastOrDefault(); } /// - /// Get data from the last n played games. + /// Get data from the last n complete played games. /// /// Number of games to retrieve - public IEnumerable GetLastNGamesData(int nGames) + public IEnumerable GetLastNCompleteGamesData(int nGames) { return savedGames.TakeLast(nGames); } - public void Save() - { - string json = JsonUtility.ToJson(this, true); - File.WriteAllText(dataPath, json); - } + //public void Save() + //{ + // string json = JsonUtility.ToJson(this, true); + // File.WriteAllText(dataPath, json); + //} private void CheckSaveFileExists() { diff --git a/projects/AstroBalance/Assets/Scripts/StarCollector/StarCollectorManager.cs b/projects/AstroBalance/Assets/Scripts/StarCollector/StarCollectorManager.cs index e500ea63..89083f85 100644 --- a/projects/AstroBalance/Assets/Scripts/StarCollector/StarCollectorManager.cs +++ b/projects/AstroBalance/Assets/Scripts/StarCollector/StarCollectorManager.cs @@ -55,7 +55,7 @@ void Start() // Load last game data (if any) from file + choose time limit for this game SaveData saveData = new(saveFilename); - StarCollectorData lastGameData = saveData.GetLastGameData(); + StarCollectorData lastGameData = saveData.GetLastCompleteGameData(); if (lastGameData == null) { diff --git a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapManager.cs b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapManager.cs index 4d49c684..9f144917 100644 --- a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapManager.cs +++ b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapManager.cs @@ -76,7 +76,7 @@ void Start() private void ChooseConstellationSize() { SaveData saveData = new(saveFilename); - IEnumerable lastNGamesData = saveData.GetLastNGamesData(maxScoreGames); + IEnumerable lastNGamesData = saveData.GetLastNCompleteGamesData(maxScoreGames); int smallConstellationMaxLength = smallConstellation.GetNumberOfStars(); // We haven't played enough games, to get maxScoreGames in a row diff --git a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekManager.cs b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekManager.cs index 93b95a59..0f7fc49e 100644 --- a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekManager.cs +++ b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekManager.cs @@ -65,7 +65,9 @@ void Start() private void ChooseGameTimeLimit() { SaveData saveData = new(saveFilename); - IEnumerable lastNGamesData = saveData.GetLastNGamesData(nGamesToUpgrade); + IEnumerable lastNGamesData = saveData.GetLastNCompleteGamesData( + nGamesToUpgrade + ); if (lastNGamesData.Count() < nGamesToUpgrade) { From ed3da6e0ada0484ede9c9496e4993bb72bbd0728 Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Tue, 10 Feb 2026 12:02:20 +0000 Subject: [PATCH 03/14] read csv values via a generic dictionary --- .../AstroBalance/Assets/Scripts/GameData.cs | 39 +++++++++++++++ .../AstroBalance/Assets/Scripts/SaveData.cs | 50 +++++++++++++++++-- .../Assets/Scripts/StarSeek/StarSeekData.cs | 13 +++++ 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/GameData.cs b/projects/AstroBalance/Assets/Scripts/GameData.cs index 4a30477f..e8ae0a22 100644 --- a/projects/AstroBalance/Assets/Scripts/GameData.cs +++ b/projects/AstroBalance/Assets/Scripts/GameData.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; +using UnityEditor.PackageManager.UI; +using static UnityEngine.Rendering.DebugUI; /// /// Base class for a single game's save data. @@ -21,6 +24,27 @@ public GameData() startTime = DateTime.Now.ToString("HH:mm:ss"); } + public GameData(Dictionary headerToValue) + { + date = headerToValue["date"]; + startTime = headerToValue["startTime"]; + endTime = headerToValue["endTime"]; + gameCompleted = bool.Parse(headerToValue["gameCompleted"]); + } + + //public GameData(string csvHeader, string csvRow) + //{ + // string[] fieldNames = csvHeader.Split(','); + // string[] csvValues = csvRow.Split(","); + + // Type type = this.GetType(); + // for (int i = 0; i < fieldNames.Length; i++) + // { + // FieldInfo field = type.GetField(fieldNames[i]); + // field.SetValue(this, (field.GetType()) csvValues[i]); + // } + //} + public void LogEndTime() { endTime = DateTime.Now.ToString("HH:mm:ss"); @@ -63,6 +87,21 @@ private FieldInfo[] GetFields() return sortedFields; } + private string ToCsvString(T[] values) + { + StringBuilder csvString = new StringBuilder(); + + for (int i = 0; i < values.Count(); i++) + { + csvString.Append(values[i]); + if (i < values.Length - 1) + { + csvString.Append(","); + } + } + return csvString.ToString(); + } + public virtual string ToCsvHeader() { StringBuilder header = new StringBuilder(); diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 618bcfab..ebc1f3e0 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -11,7 +12,7 @@ /// The type of game data (specific to each mini-game) [System.Serializable] public class SaveData - where T : GameData + where T : GameData, new() { public bool saveFileExists = false; public List savedGames = new List(); @@ -57,7 +58,15 @@ public T GetLastCompleteGameData() return null; } - return savedGames.LastOrDefault(); + IEnumerable lastGameData = GetLastNCompleteGamesData(1); + if (lastGameData.Count() != 1) + { + return null; + } + else + { + return lastGameData.ElementAt(0); + } } /// @@ -66,7 +75,42 @@ public T GetLastCompleteGameData() /// Number of games to retrieve public IEnumerable GetLastNCompleteGamesData(int nGames) { - return savedGames.TakeLast(nGames); + List lastCompleteGames = new List(); + if (!saveFileExists) + { + return lastCompleteGames; + } + + IEnumerable csvLines = File.ReadLines(dataPath); + string header = csvLines.First(); + int lineNo = csvLines.Count() - 1; + + // Start from end of file, and find n complete games + while (lineNo > 0 && csvLines.Count() < nGames) + { + string line = File.ReadLines(dataPath).ElementAt(lineNo); + T gameData = Activator.CreateInstance(typeof(T), CreateCsvLineDict(header, line)) as T; + if (gameData.gameCompleted) + { + lastCompleteGames.Append(gameData); + } + lineNo--; + } + + return lastCompleteGames; + } + + private Dictionary CreateCsvLineDict(string csvHeader, string csvRow) + { + string[] headerNames = csvHeader.Split(','); + string[] values = csvRow.Split(","); + Dictionary headerToValue = new(); + + for (int i = 0; i < headerNames.Length; i++) + { + headerToValue.Add(headerNames[i], values[i]); + } + return headerToValue; } //public void Save() diff --git a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs index c6b5be62..abc488f7 100644 --- a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + /// /// Save data for a single star seek session /// @@ -7,6 +10,16 @@ public class StarSeekData : GameData public int timeLimitSeconds; public int nStarsCollected; + public StarSeekData() + : base() { } + + public StarSeekData(Dictionary headerToValue) + : base(headerToValue) + { + timeLimitSeconds = Int32.Parse(headerToValue["timeLimitSeconds"]); + nStarsCollected = Int32.Parse(headerToValue["nStarsCollected"]); + } + //public override string ToCsvHeader() //{ // string csvHeader = base.ToCsvHeader(); From df6b46b367a37956821ca355980050e206750fa2 Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Tue, 10 Feb 2026 12:30:40 +0000 Subject: [PATCH 04/14] explicitly state export order of fields --- .../AstroBalance/Assets/Scripts/GameData.cs | 89 ++----------------- .../Assets/Scripts/StarSeek/StarSeekData.cs | 17 ++-- 2 files changed, 18 insertions(+), 88 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/GameData.cs b/projects/AstroBalance/Assets/Scripts/GameData.cs index e8ae0a22..af29b777 100644 --- a/projects/AstroBalance/Assets/Scripts/GameData.cs +++ b/projects/AstroBalance/Assets/Scripts/GameData.cs @@ -1,10 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Text; -using UnityEditor.PackageManager.UI; -using static UnityEngine.Rendering.DebugUI; /// /// Base class for a single game's save data. @@ -32,62 +29,22 @@ public GameData(Dictionary headerToValue) gameCompleted = bool.Parse(headerToValue["gameCompleted"]); } - //public GameData(string csvHeader, string csvRow) - //{ - // string[] fieldNames = csvHeader.Split(','); - // string[] csvValues = csvRow.Split(","); - - // Type type = this.GetType(); - // for (int i = 0; i < fieldNames.Length; i++) - // { - // FieldInfo field = type.GetField(fieldNames[i]); - // field.SetValue(this, (field.GetType()) csvValues[i]); - // } - //} - public void LogEndTime() { endTime = DateTime.Now.ToString("HH:mm:ss"); } - /// - /// Return info on all public fields. - /// Order is: date, startTime, endTime, gameCompleted, then any - /// other fields in alphabetical order. - /// - private FieldInfo[] GetFields() + public virtual string ToCsvHeader() { - Type type = this.GetType(); - FieldInfo[] fields = type.GetFields(); - FieldInfo[] sortedFields = new FieldInfo[fields.Length]; - - // To ensure they are always returned in the same order, - // let's sort the fields. - - // We return date, startTime, endTime, gameCompleted first (as this is general data - // for all games, and useful to have at the start of the csv) - sortedFields[0] = type.GetField("date"); - sortedFields[1] = type.GetField("startTime"); - sortedFields[2] = type.GetField("endTime"); - sortedFields[3] = type.GetField("gameCompleted"); - - // Then, all other fields sorted in alphabetical order - Array.Sort(fields, (x, y) => String.Compare(x.Name, y.Name)); - - int nextIndex = 4; - foreach (FieldInfo field in fields) - { - if (!sortedFields.Contains(field)) - { - sortedFields[nextIndex] = field; - nextIndex++; - } - } + return ToCsvString(new object[] { "date", "startTime", "endTime", "gameCompleted" }); + } - return sortedFields; + public virtual string ToCsvRow() + { + return ToCsvString(new object[] { date, startTime, endTime, gameCompleted }); } - private string ToCsvString(T[] values) + protected string ToCsvString(object[] values) { StringBuilder csvString = new StringBuilder(); @@ -101,36 +58,4 @@ private string ToCsvString(T[] values) } return csvString.ToString(); } - - public virtual string ToCsvHeader() - { - StringBuilder header = new StringBuilder(); - FieldInfo[] fields = GetFields(); - - for (int i = 0; i < fields.Length; i++) - { - header.Append(fields[i].Name); - if (i < fields.Length - 1) - { - header.Append(","); - } - } - return header.ToString(); - } - - public virtual string ToCsvRow() - { - StringBuilder row = new StringBuilder(); - FieldInfo[] fields = GetFields(); - - for (int i = 0; i < fields.Length; i++) - { - row.Append(fields[i].GetValue(this)); - if (i < fields.Length - 1) - { - row.Append(","); - } - } - return row.ToString(); - } } diff --git a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs index abc488f7..4229eadf 100644 --- a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs @@ -20,10 +20,15 @@ public StarSeekData(Dictionary headerToValue) nStarsCollected = Int32.Parse(headerToValue["nStarsCollected"]); } - //public override string ToCsvHeader() - //{ - // string csvHeader = base.ToCsvHeader(); - // csvHeader += "timeLimitSeconds,nStarsCollected"; - // return csvHeader; - //} + public override string ToCsvHeader() + { + string header = base.ToCsvHeader(); + return ToCsvString(new object[] { header, "timeLimitSeconds", "nStarsCollected" }); + } + + public override string ToCsvRow() + { + string row = base.ToCsvRow(); + return ToCsvString(new object[] { row, timeLimitSeconds, nStarsCollected }); + } } From 1baf592fdb68fb74ecf5db292f7cc11c9d4f0326 Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:28:15 +0000 Subject: [PATCH 05/14] add required csv export to more game data --- .../Scripts/RocketLaunch/RocketLaunchData.cs | 25 +++++++++++ .../AstroBalance/Assets/Scripts/SaveData.cs | 27 +---------- .../Scripts/SpaceWalking/SpaceWalkingData.cs | 24 ++++++++++ .../Assets/Scripts/StarMap/StarMapData.cs | 45 +++++++++++++++++++ 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs b/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs index e876a5b9..d0d0548c 100644 --- a/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs +++ b/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + /// /// Save data for a single rocket launch session /// @@ -6,4 +9,26 @@ public class RocketLaunchData : GameData { public bool pitch; // true if head pitch was used, false if yaw was used public int launchTimeSeconds; + + public RocketLaunchData() + : base() { } + + public RocketLaunchData(Dictionary headerToValue) + : base(headerToValue) + { + pitch = bool.Parse(headerToValue["pitch"]); + launchTimeSeconds = Int32.Parse(headerToValue["launchTimeSeconds"]); + } + + public override string ToCsvHeader() + { + string header = base.ToCsvHeader(); + return ToCsvString(new object[] { header, "pitch", "launchTimeSeconds" }); + } + + public override string ToCsvRow() + { + string row = base.ToCsvRow(); + return ToCsvString(new object[] { row, pitch, launchTimeSeconds }); + } } diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index ebc1f3e0..957fca39 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using NUnit.Framework.Constraints; -using UnityEditor.Experimental.GraphView; using UnityEngine; /// @@ -20,7 +18,7 @@ public class SaveData /// /// Create a new Save Data collection. If available, this will - /// be populated with previous save data from filename.json + /// be build on previous save data from filename.csv /// /// The filename of the save file public SaveData(string filename) @@ -113,12 +111,6 @@ private Dictionary CreateCsvLineDict(string csvHeader, string cs return headerToValue; } - //public void Save() - //{ - // string json = JsonUtility.ToJson(this, true); - // File.WriteAllText(dataPath, json); - //} - private void CheckSaveFileExists() { if (File.Exists(dataPath)) @@ -130,21 +122,4 @@ private void CheckSaveFileExists() saveFileExists = false; } } - - /// - /// Load data about previous games from file (if any). - /// - private void Load() - { - if (File.Exists(dataPath)) - { - string json = File.ReadAllText(dataPath); - SaveData loadedData = JsonUtility.FromJson>(json); - - if (loadedData.savedGames != null) - { - this.savedGames = loadedData.savedGames; - } - } - } } diff --git a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs index 749758de..c1fd66e7 100644 --- a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs +++ b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + /// /// Save data for a single space walking session /// @@ -5,4 +8,25 @@ public class SpaceWalkingData : GameData { public int nSteps; + + public SpaceWalkingData() + : base() { } + + public SpaceWalkingData(Dictionary headerToValue) + : base(headerToValue) + { + nSteps = Int32.Parse(headerToValue["nSteps"]); + } + + public override string ToCsvHeader() + { + string header = base.ToCsvHeader(); + return ToCsvString(new object[] { header, "nSteps" }); + } + + public override string ToCsvRow() + { + string row = base.ToCsvRow(); + return ToCsvString(new object[] { row, nSteps }); + } } diff --git a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs index d351a3e9..a8c58d09 100644 --- a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + /// /// Save data for a single star map session /// @@ -8,4 +11,46 @@ public class StarMapData : GameData public int maxSequenceLength; public string repeatOrder; // string representation of StarMapManager.RepeatOrder enum public string constellationSize; // string representation of StarMapManager.ConstellationSize enum + + public StarMapData() + : base() { } + + public StarMapData(Dictionary headerToValue) + : base(headerToValue) + { + nSequencesRepeated = Int32.Parse(headerToValue["nSequencesRepeated"]); + maxSequenceLength = Int32.Parse(headerToValue["maxSequenceLength"]); + repeatOrder = headerToValue["repeatOrder"]; + constellationSize = headerToValue["constellationSize"]; + } + + public override string ToCsvHeader() + { + string header = base.ToCsvHeader(); + return ToCsvString( + new object[] + { + header, + "nSequencesRepeated", + "maxSequenceLength", + "repeatOrder", + "constellationSize", + } + ); + } + + public override string ToCsvRow() + { + string row = base.ToCsvRow(); + return ToCsvString( + new object[] + { + row, + nSequencesRepeated, + maxSequenceLength, + repeatOrder, + constellationSize, + } + ); + } } From d744ca554c403005f12d9e3e9953236b443c5f6f Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:29:33 +0000 Subject: [PATCH 06/14] move csv read and write functions to SaveData --- .../AstroBalance/Assets/Scripts/GameData.cs | 36 --------- .../Scripts/RocketLaunch/RocketLaunchData.cs | 25 ------ .../AstroBalance/Assets/Scripts/SaveData.cs | 79 +++++++++++++++++-- .../Scripts/SpaceWalking/SpaceWalkingData.cs | 24 ------ .../Assets/Scripts/StarMap/StarMapData.cs | 45 ----------- .../Assets/Scripts/StarSeek/StarSeekData.cs | 25 ------ 6 files changed, 71 insertions(+), 163 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/GameData.cs b/projects/AstroBalance/Assets/Scripts/GameData.cs index af29b777..14afc2f1 100644 --- a/projects/AstroBalance/Assets/Scripts/GameData.cs +++ b/projects/AstroBalance/Assets/Scripts/GameData.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; /// /// Base class for a single game's save data. @@ -21,41 +18,8 @@ public GameData() startTime = DateTime.Now.ToString("HH:mm:ss"); } - public GameData(Dictionary headerToValue) - { - date = headerToValue["date"]; - startTime = headerToValue["startTime"]; - endTime = headerToValue["endTime"]; - gameCompleted = bool.Parse(headerToValue["gameCompleted"]); - } - public void LogEndTime() { endTime = DateTime.Now.ToString("HH:mm:ss"); } - - public virtual string ToCsvHeader() - { - return ToCsvString(new object[] { "date", "startTime", "endTime", "gameCompleted" }); - } - - public virtual string ToCsvRow() - { - return ToCsvString(new object[] { date, startTime, endTime, gameCompleted }); - } - - protected string ToCsvString(object[] values) - { - StringBuilder csvString = new StringBuilder(); - - for (int i = 0; i < values.Count(); i++) - { - csvString.Append(values[i]); - if (i < values.Length - 1) - { - csvString.Append(","); - } - } - return csvString.ToString(); - } } diff --git a/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs b/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs index d0d0548c..e876a5b9 100644 --- a/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs +++ b/projects/AstroBalance/Assets/Scripts/RocketLaunch/RocketLaunchData.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; - /// /// Save data for a single rocket launch session /// @@ -9,26 +6,4 @@ public class RocketLaunchData : GameData { public bool pitch; // true if head pitch was used, false if yaw was used public int launchTimeSeconds; - - public RocketLaunchData() - : base() { } - - public RocketLaunchData(Dictionary headerToValue) - : base(headerToValue) - { - pitch = bool.Parse(headerToValue["pitch"]); - launchTimeSeconds = Int32.Parse(headerToValue["launchTimeSeconds"]); - } - - public override string ToCsvHeader() - { - string header = base.ToCsvHeader(); - return ToCsvString(new object[] { header, "pitch", "launchTimeSeconds" }); - } - - public override string ToCsvRow() - { - string row = base.ToCsvRow(); - return ToCsvString(new object[] { row, pitch, launchTimeSeconds }); - } } diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 957fca39..939bed30 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; +using System.Text; using UnityEngine; /// @@ -38,11 +40,11 @@ public void SaveGameData(T gameData) { if (!saveFileExists) { - sw.WriteLine(gameData.ToCsvHeader()); + sw.WriteLine(GameDataToCsv(gameData, true)); saveFileExists = true; } - sw.WriteLine(gameData.ToCsvRow()); + sw.WriteLine(GameDataToCsv(gameData, false)); } } @@ -84,10 +86,11 @@ public IEnumerable GetLastNCompleteGamesData(int nGames) int lineNo = csvLines.Count() - 1; // Start from end of file, and find n complete games - while (lineNo > 0 && csvLines.Count() < nGames) + while (lineNo > 0 && lastCompleteGames.Count() < nGames) { string line = File.ReadLines(dataPath).ElementAt(lineNo); - T gameData = Activator.CreateInstance(typeof(T), CreateCsvLineDict(header, line)) as T; + + T gameData = CsvToGameData(header, line); if (gameData.gameCompleted) { lastCompleteGames.Append(gameData); @@ -98,17 +101,77 @@ public IEnumerable GetLastNCompleteGamesData(int nGames) return lastCompleteGames; } - private Dictionary CreateCsvLineDict(string csvHeader, string csvRow) + private T CsvToGameData(string csvHeader, string csvRow) { string[] headerNames = csvHeader.Split(','); string[] values = csvRow.Split(","); - Dictionary headerToValue = new(); + T gameData = new(); for (int i = 0; i < headerNames.Length; i++) { - headerToValue.Add(headerNames[i], values[i]); + FieldInfo field = typeof(T).GetField(headerNames[i]); + field.SetValue(gameData, Convert.ChangeType(values[i], field.FieldType)); + } + + return gameData; + } + + private string GameDataToCsv(T gameData, bool header) + { + StringBuilder csvString = new StringBuilder(); + FieldInfo[] fields = GetFields(gameData); + + for (int i = 0; i < fields.Length; i++) + { + if (header) + { + csvString.Append(fields[i].Name); + } + else + { + csvString.Append(fields[i].GetValue(gameData)); + } + if (i < fields.Length - 1) + { + csvString.Append(","); + } + } + + return csvString.ToString(); + } + + /// + /// Return info on all public fields. + /// Order is: date, startTime, endTime, gameCompleted, then any + /// other fields in alphabetical order. + /// + private FieldInfo[] GetFields(T gameData) + { + Type type = gameData.GetType(); + FieldInfo[] fields = type.GetFields(); + FieldInfo[] sortedFields = new FieldInfo[fields.Length]; + + // We return date, startTime, endTime, gameCompleted first (as this is general data + // for all games, and useful to have at the start of the csv) + sortedFields[0] = type.GetField("date"); + sortedFields[1] = type.GetField("startTime"); + sortedFields[2] = type.GetField("endTime"); + sortedFields[3] = type.GetField("gameCompleted"); + + // Then, all other fields sorted in alphabetical order + Array.Sort(fields, (x, y) => String.Compare(x.Name, y.Name)); + + int nextIndex = 4; + foreach (FieldInfo field in fields) + { + if (!sortedFields.Contains(field)) + { + sortedFields[nextIndex] = field; + nextIndex++; + } } - return headerToValue; + + return sortedFields; } private void CheckSaveFileExists() diff --git a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs index c1fd66e7..749758de 100644 --- a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs +++ b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingData.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; - /// /// Save data for a single space walking session /// @@ -8,25 +5,4 @@ public class SpaceWalkingData : GameData { public int nSteps; - - public SpaceWalkingData() - : base() { } - - public SpaceWalkingData(Dictionary headerToValue) - : base(headerToValue) - { - nSteps = Int32.Parse(headerToValue["nSteps"]); - } - - public override string ToCsvHeader() - { - string header = base.ToCsvHeader(); - return ToCsvString(new object[] { header, "nSteps" }); - } - - public override string ToCsvRow() - { - string row = base.ToCsvRow(); - return ToCsvString(new object[] { row, nSteps }); - } } diff --git a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs index a8c58d09..d351a3e9 100644 --- a/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; - /// /// Save data for a single star map session /// @@ -11,46 +8,4 @@ public class StarMapData : GameData public int maxSequenceLength; public string repeatOrder; // string representation of StarMapManager.RepeatOrder enum public string constellationSize; // string representation of StarMapManager.ConstellationSize enum - - public StarMapData() - : base() { } - - public StarMapData(Dictionary headerToValue) - : base(headerToValue) - { - nSequencesRepeated = Int32.Parse(headerToValue["nSequencesRepeated"]); - maxSequenceLength = Int32.Parse(headerToValue["maxSequenceLength"]); - repeatOrder = headerToValue["repeatOrder"]; - constellationSize = headerToValue["constellationSize"]; - } - - public override string ToCsvHeader() - { - string header = base.ToCsvHeader(); - return ToCsvString( - new object[] - { - header, - "nSequencesRepeated", - "maxSequenceLength", - "repeatOrder", - "constellationSize", - } - ); - } - - public override string ToCsvRow() - { - string row = base.ToCsvRow(); - return ToCsvString( - new object[] - { - row, - nSequencesRepeated, - maxSequenceLength, - repeatOrder, - constellationSize, - } - ); - } } diff --git a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs index 4229eadf..2191334a 100644 --- a/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs +++ b/projects/AstroBalance/Assets/Scripts/StarSeek/StarSeekData.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; - /// /// Save data for a single star seek session /// @@ -9,26 +6,4 @@ public class StarSeekData : GameData { public int timeLimitSeconds; public int nStarsCollected; - - public StarSeekData() - : base() { } - - public StarSeekData(Dictionary headerToValue) - : base(headerToValue) - { - timeLimitSeconds = Int32.Parse(headerToValue["timeLimitSeconds"]); - nStarsCollected = Int32.Parse(headerToValue["nStarsCollected"]); - } - - public override string ToCsvHeader() - { - string header = base.ToCsvHeader(); - return ToCsvString(new object[] { header, "timeLimitSeconds", "nStarsCollected" }); - } - - public override string ToCsvRow() - { - string row = base.ToCsvRow(); - return ToCsvString(new object[] { row, timeLimitSeconds, nStarsCollected }); - } } From c7a82a2df30b6898507bdc18c8b22b304bbd280e Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:41:39 +0000 Subject: [PATCH 07/14] fix addition of last complete games to list --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 2 +- .../Assets/Scripts/SpaceWalking/SpaceWalkingManager.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 939bed30..98204d82 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -93,7 +93,7 @@ public IEnumerable GetLastNCompleteGamesData(int nGames) T gameData = CsvToGameData(header, line); if (gameData.gameCompleted) { - lastCompleteGames.Append(gameData); + lastCompleteGames.Add(gameData); } lineNo--; } diff --git a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingManager.cs b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingManager.cs index 712691ec..b34f5fbd 100644 --- a/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingManager.cs +++ b/projects/AstroBalance/Assets/Scripts/SpaceWalking/SpaceWalkingManager.cs @@ -86,7 +86,9 @@ void Start() private void ChooseGameDifficulty() { SaveData saveData = new(saveFilename); - IEnumerable lastNGamesData = saveData.GetLastNGamesData(nGamesToUpgrade); + IEnumerable lastNGamesData = saveData.GetLastNCompleteGamesData( + nGamesToUpgrade + ); if (debugHeadTurns) { From d62557c6270f6aa8b3cf30a38f858ed2cd8d5d4b Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Wed, 11 Feb 2026 15:55:47 +0000 Subject: [PATCH 08/14] buffer null exception fix --- projects/AstroBalance/Assets/Scripts/TrackerBuffers.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/AstroBalance/Assets/Scripts/TrackerBuffers.cs b/projects/AstroBalance/Assets/Scripts/TrackerBuffers.cs index 568e2121..10b72bc8 100644 --- a/projects/AstroBalance/Assets/Scripts/TrackerBuffers.cs +++ b/projects/AstroBalance/Assets/Scripts/TrackerBuffers.cs @@ -297,6 +297,7 @@ protected List GetItems(long maximumAge) while ( bufferIndex != lastAddedIndex + && buffer[bufferIndex] != null && buffer[bufferIndex].TimeStampMicroSeconds() >= oldestAllowableTime ) { From 7a0cb0b294095803d68d0fc037a00d1436d01d3f Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:05:58 +0000 Subject: [PATCH 09/14] update SaveData docstrings --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 98204d82..410fa17d 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -101,6 +101,12 @@ public IEnumerable GetLastNCompleteGamesData(int nGames) return lastCompleteGames; } + /// + /// Convert csv header / row into a GameData object. + /// + /// Csv header as string (first line of csv file) + /// Csv row as string + /// GameData object with fields populated by row values private T CsvToGameData(string csvHeader, string csvRow) { string[] headerNames = csvHeader.Split(','); @@ -116,6 +122,13 @@ private T CsvToGameData(string csvHeader, string csvRow) return gameData; } + /// + /// Convert GameData object to a csv string. + /// + /// GameData to convert + /// When true, returns a csv header string (names of fields), + /// otherwise returns a csv row string (values of fields) + /// Csv string private string GameDataToCsv(T gameData, bool header) { StringBuilder csvString = new StringBuilder(); From e3bcd3e814f24b8522d8be5afe46a52f7782167b Mon Sep 17 00:00:00 2001 From: Kimberly Meechan <24316371+K-Meech@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:14:13 +0000 Subject: [PATCH 10/14] fix typo in SaveData --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 410fa17d..fe48a4a5 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -20,7 +20,7 @@ public class SaveData /// /// Create a new Save Data collection. If available, this will - /// be build on previous save data from filename.csv + /// build on previous save data from filename.csv /// /// The filename of the save file public SaveData(string filename) From 10c0da74ed74c2e97cc832209f410570e5e76a91 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 31 Mar 2026 11:01:58 +0100 Subject: [PATCH 11/14] Update projects/AstroBalance/Assets/Scripts/SaveData.cs --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index fe48a4a5..80c18c7e 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -14,7 +14,7 @@ public class SaveData where T : GameData, new() { - public bool saveFileExists = false; + private bool saveFileExists = false; public List savedGames = new List(); private string dataPath; From e64cebe392325c1ce365e07735cbc8bbff45d297 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 31 Mar 2026 11:05:43 +0100 Subject: [PATCH 12/14] Update projects/AstroBalance/Assets/Scripts/SaveData.cs --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 80c18c7e..347f7131 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -129,7 +129,7 @@ private T CsvToGameData(string csvHeader, string csvRow) /// When true, returns a csv header string (names of fields), /// otherwise returns a csv row string (values of fields) /// Csv string - private string GameDataToCsv(T gameData, bool header) + private string GameDataToCsv(T gameData, bool headerOnly) { StringBuilder csvString = new StringBuilder(); FieldInfo[] fields = GetFields(gameData); From ce6ca3aba1acd2ea56b90f8688d2761c6dc44f75 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 31 Mar 2026 11:07:59 +0100 Subject: [PATCH 13/14] saveGames list is no longer in use. --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index 347f7131..a0c9890c 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -15,7 +15,6 @@ public class SaveData where T : GameData, new() { private bool saveFileExists = false; - public List savedGames = new List(); private string dataPath; /// From 00aca0dca65417e85e475de90b7ce7057d4ea253 Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Tue, 31 Mar 2026 11:16:19 +0100 Subject: [PATCH 14/14] Update variable name --- projects/AstroBalance/Assets/Scripts/SaveData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/AstroBalance/Assets/Scripts/SaveData.cs b/projects/AstroBalance/Assets/Scripts/SaveData.cs index a0c9890c..39bbfeca 100644 --- a/projects/AstroBalance/Assets/Scripts/SaveData.cs +++ b/projects/AstroBalance/Assets/Scripts/SaveData.cs @@ -125,7 +125,7 @@ private T CsvToGameData(string csvHeader, string csvRow) /// Convert GameData object to a csv string. /// /// GameData to convert - /// When true, returns a csv header string (names of fields), + /// When true, returns a csv header string (names of fields), /// otherwise returns a csv row string (values of fields) /// Csv string private string GameDataToCsv(T gameData, bool headerOnly) @@ -135,7 +135,7 @@ private string GameDataToCsv(T gameData, bool headerOnly) for (int i = 0; i < fields.Length; i++) { - if (header) + if (headerOnly) { csvString.Append(fields[i].Name); }