As we worked through the Monopoly project, we had an alternative task of writing up a game pitch to be submitted and then evaluated by the department staff for production in our Capstone. During this process they would choose 4 games that the Design, Art and Animation teams would split up and work on. While I did not have a name for the game at the time of submission, it was a simple 2D Metroid-vania style game that was influenced by older generations of JRPG's in story and theme. Toward the end of the Monopoly project the Capstone projects were chosen, and my submission was one of the four chosen to be developed throughout the Capstone cycle.
(Some excerpts of the pitch can be found below)
The game I proposed at the time of submission was unnamed but became known as Soulstone early into development. While there wasn't a ton of information on requirements at the time of creating the pitch, we learned that the game had to be created using 3D assets and have a mobile build for either the provided Samsung Galaxy Tab S2 or iPad Mini 2. With those requirements, we shifted the game to be a 2.5D platformer focused on combat and exploration. Additionally, the original scope of the game entailed the player working through 4 zones of gameplay which was trimmed down to just the tutorial level known as "The Crypts" for the time frame we had.
While there was a large amount of work put into this project from all departments, I wanted to focus on the 3 major learning experiences I had during this process.
Procedural Generation
One of the many things we played with in the beginning and tried to implement into the game was Procedural Generation of our levels. Early in the project we had the suggestion of trying to do some sort of randomized content to keep the player interested in the experience as they go through it. Since a majority of the document was written as a linear path, I looked into implementation of Procedural Generation that might best suit our needs for this game. Ultimately, after much research into the topic, I landed on using an implementation along the lines of what Spelunky or Dead Cells used for their games. Instead of focusing on a complete generation of everything, we focused instead on a generation of the 'Sections' or Rooms while still maintaining a linear path to the end. These offshoots would generate out randomly with some flavor lore dropped that the player would have to work through in order to progress out of the level.
Since I worked through the Level Layouts prior to this decision I went back to the drawing board on them to ensure we could create rooms out of each to make the generation work without putting an exceeding strain on art for the asset creation. On the back end of things, one of the two additional designers on the project, Logan Swenson, worked to engineer a robust system that was modular and had the additions we needed for good game flow much as teleporters and keys. After some time tinkering, we had a system that worked extremely well but ran into the problem of odd generations and lackluster gameplay through an overwhelming feeling of repetition. To solve both issues we worked to create several additional rooms, caps and hallways to mix up the generation.
Ultimately, while this system was a success and the implementation were what we were looking at for the game, we had to scrap the system due to a lack of time and cohesion with the more linear parts of the levels. One of the many things we learned with this system though was that we could create a myriad of gameplay when we tested it with minimal additional assets if the pipeline is setup to support it. Below you can find some screenshots of the generation we had within 2 of our levels. If you would like to see more on the Procedural Generation system and how robust we were able to get it, you can check out Logan's breakdown HERE.
Player and Enemy Systems
A bulk of the scripting implementation I worked on for this project was the creation of the Core Player Systems and the Enemy Systems. My goal with each of these was to push the bounds of the scripting knowledge I had up to this point by implementing each of these systems with far more modularity than any other project worked on prior. To accomplish this, I researched further into C# and Unity to understand its systems and focused on a stable inheritance structure that we could call upon to make additions to the player and/or create a new enemy in minutes.
While this was easier said than done in the beginning due to never dabbling into this prior, its extreme power was not lost on me after it was successfully implemented. For the player, I opted out of using any inheritance since it didn't make since after looking into it further but instead, I focused on making it as modular as possible. This modularity when it came time for our other designer, Shimu Wang, to implement our Player Ability System but it had its limitations in the form of unnecessary complexity. The inheritance really kicked in with the Enemy Base and AI scripts though as they allowed for me to create variants without much additional scripts but also ensured that they followed an established convention upon creation of a new unit. Below you can find some screenshots of the code and links to Github if you would like to look more thoroughly.
While I find the systems on both ends to be usable, they are far from perfect or production worthy. The player was responsive but looking back there are a number of changes in terms of references required and its disconnect from its other systems that I would reconsider in the cases that it might not be able to access that information for some reason in the future causing some frustrating bugs. A large portion of the scripts we had were setup as singletons to get around this but after speaking with several experienced programmers this is not a good solution for that problem and would need to be reworked.
As for the enemy implementations, I would consider them a success with the exception of some major limitations due how they were built out. Given a good amount of time a restructure would definitely need to be done. While they do perform the tasks required of them, there are a number of hitches within the logic due to their dependence on sibling scripts that cause them to be clunky and sluggish on performing certain actions. In the future, I would look more down the road of using a behavior tree system to have a more robust setup without as many hiccups.
Integration and Optimization
While the good portion of my time on the project was working with the other designers to get a good feel on gameplay and systems, a much larger portion of my time was sent on the asset integration, build management and production assistance. While we were required to use Unity engine to create our games, we decided early on to use a newer version of the asset render pipeline known as the Lightweight Render Pipeline. This presented a number of challenges to the project but chief among which was that there is little to no official documentation on this pipeline as of yet since it is a preview feature for Unity. This was an issue as many answers had to be dug for or tested out personally. One of these issues arose in our lighting pipeline. While this wasn't a huge hiccup, due to the lighting limitations within the Lightweight Pipeline we needed to switch to a baked lighting process which took some digging and understanding of the pipelines limitations to understand. However, due to the pipeline's strengths on multiple fronts, it worked in our favor and time was spent to ensure any issues or questions that our art team had were answered.
Additionally, working through a mini-Producer in a way was another big part of the time spent on the job. Ensuring that everyone had what they needed and getting timetables to be able to integrate everything into the build was a majority of my in class time; along with assistance of issues that cropped up. On the design end of things this culminated into the pushing my peers into learning more about the features of C# and Unity that we hadn't learned in class such as Inheritance and Polymorphism proper, Events, Memory Management and Multi-threading for our code. While we did not dive super deep into a majority of these topics, each of them provided a boost to issues we had on the project toward the end which greatly helped in the efficiency of the project.
An End but a Beginning
I learned a lot from this project and even more so from my peers and the production cycle itself. It has made me hungry for a chance to join a larger project and team to see what awesome things we can create. While the game is rough around the edges it was able give all of us a good gauge of our skills and abilities. However, I also leave the judgement up to others. If you would like to player through the game, you can download the build using the links below.
** This project was built for 2048 x 1536 resolution. For the best experience on Android, please use a tablet or phone with this resolution. **
** Alternatively you can use the Windows build. **
Back to Top