If there’s one thing that people know about me, I’m unapologetic about my hobbies, and out of that tends to come a passion project or two. Outside of coding, I love sim-racing, I love cars, and I love to write, amongst other things. So when an opportunity presents itself for me to combine some of these, I become easily carried away into the thick of it.
A few months ago I resumed storyboarding a project I’m working on part-time, and arrived at a crossroad. The story had become quite complex, and I was easily losing track of important details. If only there was some way for me to see everything relevant at a glance.
It’s not like that was a direct requirement of the project I was developing at work. Right?
Build The Tool – Passion Project Initial Requirements
The story in ques…
If there’s one thing that people know about me, I’m unapologetic about my hobbies, and out of that tends to come a passion project or two. Outside of coding, I love sim-racing, I love cars, and I love to write, amongst other things. So when an opportunity presents itself for me to combine some of these, I become easily carried away into the thick of it.
A few months ago I resumed storyboarding a project I’m working on part-time, and arrived at a crossroad. The story had become quite complex, and I was easily losing track of important details. If only there was some way for me to see everything relevant at a glance.
It’s not like that was a direct requirement of the project I was developing at work. Right?
Build The Tool – Passion Project Initial Requirements
The story in question combines fantasy elements with sci-fi. The best description, in short, would be to look at the structure of characters from games like Final Fantasy 14 and anime/manga like My Hero Academia.
The Characters and Their Abilities
There are multiple abilities characters can take on, and they aren’t necessarily unique to a person. Further complicating things, not every character can or will use said ability in the same way.
All of this information exists across four different Word documents, and cross-referencing those four can become tedious. So, for our first requirement, we need to make it easy to get details on those abilities and what the specifics are per character. A database is an adequate solution, and two tables to hold this information – one for the characters, one for the abilities – will store the requisite data. And for the sake of maintaining them as they change throughout the editing process, we will store the character descriptions as well. Simple!
Following this, each character will use their abilities in different ways, with different traits they will learn throughout the story. They would have “leveled up” and mastered their traits in different ways, and so we will need to track this. We will add another table that stores these traits, and refer to them as “Manipulations”.
Character Relationships
Next, each of these characters is related to the other through the different parties they are in. This one, unlike abilities, is unique to a group of characters. There must be five to a party – no more, no less, but a character may not be associated with one. This brings about our fourth database table – one that contains a basic level of information about a squad. For now, it will just be the squad name.
Spread Out The Data
From here, we now run into the issue of a lopsided amount of data to a table. The Character table will contain a significant amount of information, as we’re saving their entire description. To solve this, we will create two new tables. One will store the character’s physical description – we’ll refer to this table as the “Physique” table. The next will store the character’s individual abilities and information as to how they have progressed with them. This separation of data will keep the tables appropriately sized and store the most relevant information at that moment.
Looking at the structure of this so far, I began to notice a pattern. I was following exactly the same database structure that we were using on a project I was actively working on, and applying it to this passion project. And more importantly, it was working. I decided to keep going with this plan, thinking about what stack I wanted to use as I sketched this out, but the idea was clear. If I’ll create an application while following the same pattern, then I’ll use SQL for the database and a Dotnet application for the API.
…And Off To The User – Supporting the Passion Project
Okay, now that I have conceptualized the data structure, I need to organize and access the data itself. I immediately spun up a Dotnet API, for multiple reasons. Having worked with it for an entire year, I was exceedingly comfortable with the way it operates. Moreover, it made data access super easy, supporting multiple ways to transform and connect relevant pieces in other places.
Getting The API Going
The first thing I did was create the entities and their relevant types:
The relevant database entities, database objects, and enums for this passion project.
An interior look at the Character table’s entity for the project.
Once that was done, I added the requisite parts to the “Program.cs” file to get it to run as needed:
How the project will run itself.
Lastly, I created the Docker Compose file to initialize my database:
The Docker container’s creation script.
The Docker container, created for the passion project.
Working With The Data
Okay, great. I’m running the API now, and I’ve initialized my database. This is a resounding success so far! Now I need to create the accessors. The pattern I’ll follow is multi-layered – at the innermost level is the access to the raw data itself, called the repository. Here, I provide a variety of functions that gather the requested data before passing it back up to the top.
The repository layer at a glance.
Ultimate control over all the abilities.
Once the repository is finished gathering and returning the data, it goes up a level to the service level. This is where the data is modified, transferred, transformed – whatever is necessary to get the correct shape and information.
The service layer’s hierarchal structure, at a glance.
A screenshot of an interface of the ability portion of the service layer.
After all is said and done, the final data is sent back up one last time to the controller layer. Here is where the actual front-facing API lives – It accepts incoming requests and passes them down to the service layer, as well as returning completed data that it receives from below. Once the data reaches this point, it is sent back out to the user.
A screenshot of the controllers for the API project. Note there are only four – the remaining two tables are joined into the relevant objects, therefore endpoints are not needed for them.
Now all I need to do is create the necessary endpoints, and I have successfully built my tool!
A screenshot of the Swagger interface running on the API project.
Prepare The Interface – This One Trick
From here, I’ve finished the API. I want to provide a simple way to connect it to a frontend I will build. One solution to this – to further lean into the pattern replication – I can use a program called OpenAPI Generator to create an NPM package entirely based on a Swagger API link I provide to it. Contained within this NPM package will be multiple functions that effectively take in the request data as arguments, create the correct request to the API, and then receive and return the correct data to me.
After a little bit of research, I created this PowerShell script:
A screenshot of the NPM package builder script.
…And then installed the package into a UI project as seen here:
A screenshot of the package.json file on the UI portion of the passion project.
…And, after a bit of setup, was able to present the information onto a UI project:
A screenshot of the UI. It’s not perfect, but it works.
…And Off To Work – Passion Project Coming Together
In total, from start to finish, this passion project took roughly 30 hours to complete. A significant factor in that number being as small as it is is due to my strong familiarity with the technologies I used. To bring it full-circle, I successfully combined my love for coding and writing – something I do as a job, and something I do entirely for fun – to make the experience of said hobby easier. And I loved the process of doing it.
Now, once I complete my front-end, I can continue writing with ease. I’ll need to shake off the rust though, since I’m using Vue… maybe that’ll be a post of its own.