Feeling a bit overwhelmed this week… I had to do some major rework (again) instead of working on new features. I find myself battling with Unity again, specifically where to put things – prefabs, components/MonoBehaviours, ScriptableObjects, plain vanilla classes. When I first started using Unity a couple of years ago, I tended to write code for everything, because that’s what I was familiar with. As I gained familiarity with Unity, I pushed myself to embrace it and fully leverage the editor capabilities. However, that produced a lot of constraints, and now I’m back to relying on code more (though not as much as in the beginning). Anyway, a lot happened this week due having a couple of days off:
- Finished the save system. I mentioned last week on reddit that I was struggling to determine the best way to code the save system in Unity. I ended up pulling all state data out of MonoBehaviours and into plain classes for each object type. Nested objects are supported as well (serialized attributes have to be explicitly declared). All objects that need to be saved are nested in the Map class, so saving the game is as simple as serializing this class. Loading is a tad more complicated because, after deserialization, game objects have to be instantiated.
- A byproduct of the save system was changing actors and items to inherit from the same base class. There’s a lot of commonality between actors and items – they’re in-game objects, they can be damaged, have status effects, etc. I was handling this through composition. Attributes were spread across multiple MonoBehaviours. Because Monobehaviours can’t be serialized, capture/restore state code needed to be written for each component. It made more sense to move all state attributes into a single serializable class. This was a case where inheritance made more sense than composition.
- Another byproduct was pulling health into the base class from a MonoBehaviour. Previously, the Damageable component made an actor or item damageable. This component tracked health. However, each actor and item ended up needing this component so it didn’t need to be optional. Also, this was done to address the issue in the previous bullet. This change broke a lot more than I expected, but fortunately the unit tests helped pinpoint the issues quickly.
- Test map generator. The map generator can now generate a map with designated layout, actors, and items. This will allow a greater degree of automated testing.
- New map generation capabilities. Map generation now fully supports different sets of parameters. These parameter sets can be statically predefined in the Unity editor as ScriptableObjects, or dynamically generated in the initial steps of the map generator, enabling additional layers of procedural generation.
Next week, the goal is to finish the load game and select class screens, and start on the hotbar time permitting.