In this post, I am talking about the key rules we came up with when starting the project.
Quick Background
When I joined the project, there was already a demo of the game with GitHub set up. The code was messy due to being written in just one week. However, there was a good reason for this: our projects had to go through a super short prototyping phase. In just one week, we had to come up with an idea and build a prototype. We then presented these to others, who voted on which ideas should be pursued for further development.
Coming Up With The Rules
Git
After joining the project, I evaluated the situation. I took it upon myself to come up with a GitHub flow for us since it seemed like I am the most proficient with it.
We planned how we are going to go about with the git branches.
Since there’s usually a problem with the people on the art side not being too familiar with git. We decided that each member has their own branch, this was easy solution due to our team size being only six.
I told the artists that this is the only branch they need, and the only thing they need to do is push their material there.
I would then handle all the merging into Dev branch myself.
This is not intended to disrespect or diminish the value of artists on the team. Rather, it is meant to benefit everyone and reduce stress for artists, who often worry about accidentally causing problems when it comes to source control. By implementing this approach, we hope to give artists greater peace of mind.
Besides each member having their own branch, we also had the normal expected Dev
, Build
and feature-x
branches.
I took primary responsibility for managing and resolving any issues with git.
CI/CD
I wanted to create a CI/CD pipeline to create builds after pushes to the Build
branch.
I had already played around with this feature on GitHub and tested that it works. However, there was probably going to be some issues related to licenses and policy since our code was under an organization and we didn’t even have LFS
support. So, I didn’t pursue this further, and focused on the development instead.
Rules for Coding
Before starting our actual development of the project, we discussed about some principles we should follow when it comes to the code.
Them being:
- How to avoid too many dependencies
- How to comment the code
- What is useful
- How to keep the code base clean
- Folders, Namespaces, Scopes, Nested IFs
- How to avoid too much the same
- When to use interfaces
Indentation & Styling Overall
To address the problem with potential code style mismatches, tools like EditorConfig can be used along with various other tools. However, in my experience, most IDEs already use the Allman style by default for C#, so there were no issues with enforcing a particular style.
Personally, I prefer 1TBS (OTBS: One True Brace Style) which places the first curly brace on the same line as the function, followed by an indentation on the new line.
There was some debate about this style within the team, but I made sure to use the same style as the original code when working on others’ code. Fortunately, my IDE (Rider) helped with this by recognizing the style already used in the code.
Documentation
Earlier during the semester while working on my personal projects, I found out about how to use the XML comments for C#.
I shared this information with my team and introduced them to some tools that could assist us in writing clear and concise comments. We decided to use XML comments as our primary method of documentation for situations where we needed more detailed explanations than simple one-line comments could provide.
One of the main problems of using regular comments is that you cannot see them from other scripts when using a public function for example. This can be an issue when trying to remember parts of code, or use code that you didn’t write.
I found our approach to commenting, using the XML comments, to be extremely useful because it provides helpful tooltips when hovering over functions. I’m surprised that this method of commenting is not more widely taught by the people creating tutorials.
Example below – This was used to implement a simple roaming function for the AI. This was achieved by feeding it a randomized distance value, based on the AI’s min and max roaming distance given by the game designer.
Principles
Everyone on my team were familiar with SOLID and OOP, so we followed these principles by default.
I’ve heard about a rule that “once you repeat something more than 2-3 times, consider an interface.” However, in our case, where we only had 9 weeks of time for development, I told my team that we should probably keep this in mind and not spend time creating interfaces for things that only require one copy and paste.
Personally, when writing my own code there are few principles I follow the most.
- Single Responsibility
– Whenever it seems fit.
– It bothers me writing everything under the same script or function. - Interface Segregation Principle
– I like to keep my code decoupled as possible. - Encapsulation
– I’m always mindful of the scope. - KISS (Keep It Simple, Stupid)
– After reading some over engineered code and even writing some, you learn to appreciate this, and so will your teammates.
Generally, I am always trying to learn more to achieve better code quality, and I like to see what other people in the industry think about when it comes to “Clean code”.