Using ChatGPT to implement Save/Load feature


On my continued journey of exploring how far I can get using ChatGPT, I decided it was time to implement a Save/Load feature. This game can have long play sessions, so it's highly beneficial for players to save their progress and resume later.

I took an incremental approach, focusing on one game object type at a time. First, I asked ChatGPT to generate code that would save and load all paths on the map, and it created SaveLoadManager.cs:

    [System.Serializable]

    public class RoadNodeData

    {

        public Vector3 position;

        public string pathType;

        public List<string> neighborIds;

    }

    [System.Serializable]

    public class GameData

    {

        public List<RoadNodeData> roadNodes;

    }

This was a good start, but the data class was missing a unique identifier to link all nodes back into paths (neighborIds list). ChatGPT advised that I specify my identifier, so I used the object instance name since in my scene setup, they always have unique names.

Next, I tackled adding Cities. The tricky part was that cities also contain a RoadNode component, so ChatGPT suggested making the City component inherit from RoadNode instead of plain MonoBehaviour and modified the RoadNodeData class to store data for both objects:

    [System.Serializable]

    public class RoadNodeData

    {

        public string instanceName;

        public Vector3 position;

        public string pathType;

        public List<string> neighborIds;

        public bool isCity;

        public string cityName;

    }

This could work in theory, but I preferred to keep both scripts separate. I asked ChatGPT to maintain this separation, and it rewrote both classes back to the original state but kept RoadNodeData to store data for both classes with isCity to identify which is which. This wasn't ideal but workable, so I proceeded to generate more code for storing all other city data, including arrays of buildings, citizens, and resources inventory.

Starting with the simplest, the buildings list, I asked to add building data to the save function. ChatGPT initially forgot that building positions are Vector2 instead of Vector3 as they are only displayed inside the UI. From there, I pasted the data structure of buildings, inhabitants, and City inventory (one at a time), and it did a great job adding all of them to the Save and Load methods. Mind you, CityInventory had a fairly complex structure. My exact prompt for adding Inhabitants and CityInventory to SaveLoadManager:

    All right! Now let's finish with saving all city data. We still need to save Inhabitants list and Inventory.

    I will remind you that Inhabitants is set up in a following way, very similar to the buildings list:

    public class City : MonoBehaviour

    {

        [System.Serializable]

        public class InhabitantCount

        {

            public Inhabitant inhabitantType;

            public int count;

            public float happiness = 1.0f;

        }

        public List<InhabitantCount> inhabitants = new List<InhabitantCount>();

    }

    Inventory is a little bit different:

        public CityInventory inventory = new CityInventory();

    CityInventory is a different script with the following structure:

    public class CityInventory : MonoBehaviour

    {

        public List<ResourceEntry> items = new List<ResourceEntry>();

    }

    [System.Serializable]

    public class ResourceItem

    {

        public Resource resource;

        public int count;

        public ResourceItem(Resource resource, int count)

        {

            this.resource = resource;

            this.count = count;

        }

    }

    [System.Serializable]

    public class ResourceCountEntry

    {

        public Player player;

        public int count;

    }

    [System.Serializable]

    public class ResourceEntry

    {

        public Resource resourceType;

        public float price;

        public List<ResourceCountEntry> counts = new List<ResourceCountEntry>();

    }

After implementing this, I tested the save and load feature and realized I forgot about Player objects. Players owned each city and could also own transports, which I planned to implement next. Fortunately, the player class was simple, just a name, color, and gold. I added a bool value isMain to identify the non-NPC player.

    public class Player : MonoBehaviour

    {

        public string playerName;

        public Color playerColor;

        public int gold;

        public bool isMain;

        public List<Transport> ownedTransports = new List<Transport>();

        public List<City> ownedCities = new List<City>();

    }

The best part was, I said we didn't need to save ownedTransports and ownedCities as they can be recreated from restored data. Without any further instruction, ChatGPT did just that - on LoadGame(), whenever it set a city owner to that player, it also generated a line that adds the city to that player's ownedCities list.

Finally, it was time to add Transport objects. They needed just one adjustment - there was no class variable for the path it needs to travel as, so far, the transport would calculate the travel path inside a function running in a thread. So, I added a destination parameter whose job was to recreate the travel path in the Start() method if its value was not null.

One problem remained. While designing the map, I used different City prefabs to create versions such as a farm, a coal mine, and so on. The load function needed to work with just one prefab for the city to keep it compact. So, I needed a way to change the city sprite in the game without moving them to the Resources folder. I asked ChatGPT if there was a way, and it said, "Yes, use AssetBundles. Here is how..." I didn't know what an AssetBundle was, but now I do.

With this, my save and load functions were ready. So, I decided to go one step further. Since my game currently runs inside a web browser, the save game file is kept somewhere inside the browser cache, which means it can disappear if the cache is cleared or if I make another update to the game. I asked ChatGPT if there was a way to export the save file to my own hard drive and later import it back. It turns out there was. ChatGPT showed me step-by-step how to make my own WebGL template, add functionality for exporting and importing files in JavaScript, and make them work together with C# code.

And with this, I am done! A fully working Save/Load feature ready in just around two days. Next, this could be improved by adding multiple save slots and showing player progress on each slot before loading (time played, player gold, and so on).

Files

Web.zip Play in browser
95 days ago

Leave a comment

Log in with itch.io to leave a comment.