Devlog #2
Welcome back for another installment in our Devlog series! We've made quite some progress this month in making our game, Forge Industry, represent more of a game. Follow along to learn all about it. Don't want to read? You can of course also watch this Devlog on our YouTube channel, where we brought the team together to get their ideas.
As a quick recap, we're working on the automation game Forge Industry. Last month we started working on the game in our spare time and created a basic game that had some of the core mechanics, but no real playability yet. This is about to change though. For a full update, you should head over to our previous devlog.
UI improvements
One of the first things that were done was the UI. Marnix started by creating a bunch of extra mocks of the menus. These outlined the key actions the user should be able to do in every UI element. Thomas then implemented the basic UI into the game scenes functionally (but it wasn't pretty). Marnix then took over again in order to add some styling and make it look more pretty.
This led to the implementation of a pause menu as well as an actually usable save menu (Thomas had written the code for this in the previous devlog). Just from first impressions, our game looked much better now. This also made it feel much more like we made a lot of progress on our game though, as it now started to take shape as an actual game, which was pretty rewarding.
It's important to note that this UI still is nowhere near what we actually want for our end game. Instead, we are using this UI as a stepping stone between having no UI (apart from the in-engine start button) or a fully finished UI We applied the 80/20 rule for the UI. We spent 20% of the total time required on the UI and already got 80% worth of value. Once our game is nearer to completion, we will give it another overhaul. Then we can also assign William on creating custom sprites for everything as well instead of just using plain, colored borders.
Game saving
Thomas spent the first part of the sprint working on the game's save system. This was something we wanted to have finished early in the game. It would also make our life easier down the line. Instead of creating a new test game every time we want to do something, we could share a previously made save. This savefile would then feature a full in-depth setup so we can really test the scalability of our game.
There were 2 main challenges regarding the game save system. First of all was how we wanted to structure our saves, and how the user would interact with our saving. Marnix and William had some conflicting visions about this implementation in the beginning, although they got resolved in the end.
We ended up going for a 2-tiered approach in our save structure. The highest level was what we reserved to as a "profile". This can be seen as a single world the player creates. Then, each profile stored 3 kinds of actual saves. Quicksaves, autosaves, and named saves. These were all stored under a single profile, and if the player just presses "continue", whatever save is the most recent will be loaded.
As the name suggests, quicksaves are bound to a key and will immediately save the game in its current state. There can only be a single quicksave, and making a new one will overwrite the old one. Autosaves are saved periodically and are queued, after x saves, the oldest one will be replaced, with the latest save taking its place. Named saves are saves where the user actually presses the "Save Game" button. Here they can give a meaningful name to their save as well. This is especially useful if they are about to do something to which they want to easily roll back to later on in the game.
The second issue was finding a way to generically serialize (turn a game object into a file) our save data. This was especially tricky because not every game feature was implemented fully yet back then. Workers for example didn't do much except existing, with no inventory data yet for example.
We don't want to fully rewrite our save system though every time we change one of the mechanics. This is why Thomas spent quite some time figuring out how exactly to serialize. In the end, we ended up with a relatively basic but effective serialization implementation. After all, this is something that has been done plenty of times for all kinds of projects, so research was also not too bad.
Item refactors
One of the big blockers we had was the item refactoring. We couldn't work further on our crafting mechanism until we remade the way we implemented items. This is where Thomas and William put their heads together and came up with a more scalable system that combined a material with an item type, instead of having each combination be a unique entry.
Unity Playmode Testing
One of the biggest setbacks or delays we encountered was implementing our testing strategy. We had given Jamie the simple task of deleting roads or buildings. The actual coding and implementation of this feature weren't that big of an issue. After only a few hours this was implemented and all seemed to work.
However, we had just implemented a DevOps pipeline (we'll release more information about that in an upcoming video) and wanted to really get our testing strategy working. William had already implemented some Unit Tests for things like road orientation or dynamic world events. These are easy logic tests though and don't require any in-game interaction. Deleting an in-game object was harder though, as we had to simulate the actual game.
This is where Playmode testing comes in, you create a scene and mock your inputs fully code-wise, without anyone actually moving their mouse or pressing buttons. There were quite a few issues with this implementation though, such as implementing assembly definitions, or support for overriding the input library we were using, Rewired. This ended up with Jamie having to research this for weeks on end and try to get something working.
So why didn't we just drop the testing part if it took so much time? We actually could, however, everyone in the team agreed that getting these tests working would help a lot down the line to prevent pushing broken branches and limiting bugs that could appear.
Dynamic World Events
William also started working on one of the features that should make our gameplay more engaging: Dynamic world events. This will cause different kinds of scenarios in the world in which you are blacksmithing. Perhaps a war breaks between the elves and barbarians, increasing demand and the selling price for bows. Or a new king is crowned, and he requires an order of 10 decorative golden swords. Or maybe there are some events that don't even influence the actual game. Instead, they just add to the feeling that you're not just a machine automating everything.
Smaller features
We also did a bunch of other small features, which aren't exciting enough to get their own full explanation, so we've listed them here:
- There were a bunch of issues still with roads last Devlog, those have all been resolved now and they connect nicely.
- Apart from making the UI look nicer, we've also added some UI sound effects to liven up the experience.
- Now that we have a UI, we already got a first proof of concept working in regards to our multilanguage support. Current languages are English, Dutch and French as those are the languages we know best.
- Workers can now be interacted with, displaying a panel with some fun facts about them. Later on this panel will also be used for displaying its inventory and current route.
World generation
Thomas also spent the last week working on dynamic world generation. Currently, our game is just on a flat 2D plane. However, that's not really what we want to go for in our final game. We would want some level of mountains, as well as rivers going through our terrain. The plan isn't to have everything purely randomly generated. For our main 4 worlds, we want to have a static world that's the same for everyone. The random worlds can be seen more as the NewGame+ of our game if you want to spice up the game a bit.
This feature isn't completed yet, so it doesn't really count as a finished feature. Since Thomas did spend a lot time on this feature already though it does deserve a mention as part of this Devlog.
What's next for us?
In this sprint, we focused on a lot of surrounding features, instead of the core gameplay look. We now have UI and dynamic world events for example, but we still can't really buy, sell, or craft items. I think this is not ideal as we still have no idea if our game can actually be fun. That's why for this next sprint, we really need to focus on this. The mean features we'd want to see finished is:
- Having a fully functional marketplace where we can both buy and sell items
- Workers carrying items between workstations. The code for this should all be there but we haven't been able to test this
- Have a first workstation, probably the Refinement Station, fully working
These are just the features for the core gameplay though. Some other things that we are also aiming to do are:
- Getting a first working version of 3D world generation
- Moving away from the whitebox stage for our main workstations
Of course, we'll have to see how much of this we can reach. Although, I have faith in getting the item workflow working now at least. Be sure to check back next month, April 29th, for our next Devlog and to see how much we've actually made happen!