# Project Conventions
## Git
### Overview
Git is a version control system, meaning its purpose is the continuous creation and management of different versions of the same project or software. Correct usage of the system can enable multiple people to work in the same environment without conflict, making experimental changes without endangering any progress, and maintaining multiple versions with relativ ease.
To do this, it's obviously important to make use of the system properly. The main tools Git provides to this end are branches and commits.
#### Branches
A branch is a copy of the existing project state that can be freely modified without affecting any other branches. Then, the changes made can be safely discarded by deleting the branch, or, afer verifying the changes, added back to the original state by merging the branch.
#### The Main Branch
The main branch is the default branch that the repository starts out from. It is usually either named "main" or "master", but besides being the very root of the project, generally behaves like any other branch.
#### Commits
If a branch is a collection of work done in a safe environment, each commit can be considered like a unit of work in that collection. Essentially, whenever you choose to make a commit, you are essentially creating a checkpoint you can later go back to. There is essentially no reasons to not commit frequently, especially everytime you make a decision to start making a new change. That way, it is always trivial to revert changes you make and aren't happy with, or allow you to go back and experiment with a different approach without losing your current progress. The message here is: Commit often.
#### Pull Requests
A pull request is a formal request towards the rest of the team to merge the work you have done with the current main branch
#### The Usual workflow
Our repositories always feature so-called branch protection rules, that allow us to prevent all direct commits towards the main branch branch. The only way to make changes to it is by the use of pull request.
The general workflow:
- update your local version of the main branch
- create a new branch from the main branch
- make changes on that branch, bundling all change-units in commits
- create a pull request for after changes on your branch are complete
- merge the pull request after at least one approving review
- start all over!
In between steps, you are of course free to switch branches, create and work on more than one branch from the main branch at the same time, etc. Each branch should always go through this 'creation from main -> work in form of commits -> pull request towards main -> merge into main' lifecycle.
Pull requests should always follow the Pull Request Layout.
### Branch Folder Structure
Generally, every git branch besides special-purpose branches like 'master'/'main', 'develop', ..., should always be sorted into one of the following folders/categories. These folders/categories are assigned by specifying the branches name in the following format: 'folder/NameOfMyBranch'
#### Common folders/categories:
- feature/
- as the most common folder, feature/ typically contains most of the work in a repository. every addition of new content, be it code or assets, as well as the modification or upgrading of existing content that is not specifically targeted towards fixing a specific bug or issue, counts as a feature in this sense.
- examples:
- adding a new model for an npc and setting it up appropriately in the engine.
- adding more variance to the map generation by using additional noise layers.
- creating some UI and a system that allows the player to call waves earlier than they would spawn by themselves.
- changing the damage values of enemies and towers to balance the game.
- fix/
- whenever a specific issue arises, it (and only it) should be addressed in a fix/ branch. these issues could be code bugs just as well as broken assets or misnamed files.
- examples:
- a certain building has no collider, so enemies walk through it. add a new collider to it in a fix/ branch.
- some bug in code causes enemy corpses to stick around forever, piling up over time. find and eliminate the bug on a fix/ branch.
- an animation clip was misnamed during the import. rename it on a fix/ branch.
- import/
- usually used most commonly during the beginning stages of a project, this folder contains all imports of plugins and asset bundles that previously existed as a cohesive unit outside of the project. this usually specifically refers to assets that where not originally created by us, but it could mean bundles of content that we had oriinally produced for a previous project as well. when importing an asset that requires any amount of setup before it can be used, this should be done on the import/ branch as well.
- examples:
- import of asset store plugins or assets.
- import of a tool created for an earlier project.
- import of a large tool like FMOD, that requires extensive setup. that setup is done on the same branch.
- release/
- probably not very relevant initially, but should be used later to track current released versions of the game 1 to 1. 'released version' means any version created and stored or sent somewhere for anything but strictly internal testing. the purpose of tracking released versions in this manner is to be able to later refer to the state of the project at that time.
- for example, say we have created a version of the current project to present to a stakeholder (publisher, press, external testers, etc). we add a 'thank you for playing' popup and other minor, custom changes just for them, and send them a build. then, 1 month later, that stakeholder notifies us of a severe issue, that rarely occurs but makes playing impossible. because development has moved on in the meantime, our current master version differs in a way that makes reproducing the bug impossible, leaving us without any way to even check whether the reported bug is even still an issue that will pop back up in the future. here, the release/ branch comes in, allowing us to investigate that specific version, see all the custom changes and the changelog in comparison to our current master version.
### Naming
#### folders/categories
As seen in the examples above, folders/categories should usually be a single lower-case word, followed by a /.
#### branches
The branch name, meaning everything after the /, is always written in PascalCase, aka starting with a capital letter, with every consecutive word also starting with a capital letter, and no spaces in between.
In general, branch names should be evocative and descriptive of what is being done on them, but their names should remain short enough to not be annoying to type out.
#### examples
- feature/MapGeneration
- fix/EnemyDespawning
- import/OdinInspector
- release/GamescomDemo
### Pull Request Structure
Pull requests have 2 major sections: 'Feature' and 'How to Test'.
'Feature' describes what has been changed. What did you add, what did you fix, what things are new or different? Always list what is most relevant to the work you did, in the way it makes sense for that work. If you wrote code, don't bother listing any filenames, just list what new functionality you introduced and where, whether any data was changed, etc. If you import assets, list the new assets and what they are for. If you did some gameplay balancing, say what the effect of your changes are and maybe link to any spreadsheets etc you made.
How detailed you document your changes is ultimately up to you, but it should be sufficient for anyone checking your pull request to understand what it is for and why it exists.
'How to Test' then instructs the readers of your pull request how to make sure your stuff is working and intact. of course, this also depends on what specifically was changed, but here are some examples: If you wrote code, explain the scenario in the game or editor that now functions / functions differently. If it's particularly convoluted, explain how to get there. You can of course assume that testers have a certain level of familiarity with the game, but it is eg always a good idea to tell them what scene to load, what situation to create, whether they need to be in play mode, etc. If you created new visual assets, tell them where to find a test scene to look at them. If you did any gameplay balancing, explain what scene to start from, maybe how to get to or cheat those enemies changed and what values to look out for.
This section should be sufficient for anyone familiar with the subject to verify that the changes you made actually work.
## Unity
### Project Files Location
Because Unity has the habit of just slamming your asset folder with imported plugins & asset, our strategy is to create a folder to only contain Assets and Files directly created by us. That folder will always have the exact same name as the project itself, so the path from the Unity Project Folder will always be ProjectName/Assets/ProjectName.
This folder is the place where all things that we introduce to the project go, besides plugins & packages. We call this folder the project folder. This structure draws a clear distinction between "project stuff" and "external stuff".
Inside the project folder, we split up into 3 subfolders: 'Assets', 'Runtime', and 'Editor'. While the purpose of Assets may be immediately clear, as it contains everything you would usually just have put into the top level asset folder, 'Runtime' and 'Editor' are both scripts folders.
'Editor' is the Unity mandated name for a folder containing scripts that are not compiled into a build as they contain Editor-only functionality, and 'Runtime' is an arbitrary name chosen to best contrast 'Editor' as "the other scripts folder". 'Runtime' contains all scripts that are meant to exist in a build.
The purpose of splitting these folder like this is that in my opinion, it makes it rather straightforward to define where any given script should go, but also makes adding top-level assembly definitions trivial. Simply add an editor only definition to the 'Editor' folder, and an all-platforms definition to the 'Runtime' folder. This also allows setting up root namespaces while you're at it.
Forgoing a scripts parent folder is a conscious choice - it simply seems redundant.
The 'Assets' folder within the project folder contains, as this folder structure suggests, all assets made for this project. It may be split up into sub folders as one usually would, for Meshes, Materials, Shaders, Cofigurations, etc.
### File Structure
Inside our projects asset folder, assets should be sorted a certain way. They are generally organised by type, so the top-level folders in the projects asset folder correspond to a file type each: Materials, Meshes, Shaders, etc.
Inside these top-level folders, assets are structured by purpose: In the Meshes folder, you may find a folder containing all Meshes for buildings, specifically, while the SoundAssets folder may contain another named SoundTracks.
> Folder Structure
> Materials
> GUI
> Effects
> Meshes
> Actors
> DarkVampire
> LightVampire
> ...
> Structures
> Buildings
> ...
> Props
> Plants
> ...
> ...
> Plugins
> Prefabs
> Actors
> Items
> ...
> Resources
> Actors
> Items
> ...
> Scenes
> GUI
> Levels
> TestScenes
> Scripts
> Textures
> GUI
> Effects
> ...
> Scene Structure
> Cameras
> Dynamic Objects
> Gameplay
> Actors
> Items
> ...
> GUI
> HUD
> PauseMenu
> ...
> Management
> Lights
> World
> Ground
> Props
> Structure
> ...
### Naming Convention
#### Naming General Principles
1. Call a thing what it is. A bird should be called Bird.
1. Choose names that can be pronounced and remembered. If you make a Mayan game, do not name your level QuetzalcoatisReturn.
1. Be consistent. When you choose a name, stick to it.
1. Use Pascal case, like this: ComplicatedVerySpecificObject. Do not use spaces, underscores, or hyphens, with one exception (see Naming Different Aspects of the Same Thing).
1. Do not use version numbers, or words to indicate their progress (WIP, final).
1. Do not use abbreviations:Â DVamp@W should be DarkVampire@Walk.
1. Use the terminology in the design document: if the document calls the die animation Die, then use DarkVampire@Die, not DarkVampire@Death.
1. Keep the most specific descriptor on the left: DarkVampire, not VampireDark; PauseButton, not ButtonPaused. It is, for instance, easier to find the pause button in the inspector if not all buttons start with the word Button. (Many people prefer it the other way around, because that makes grouping more obvious visually. Names are not for grouping though, folders are. Names are to distinguish objects of the same type so that they can be located reliably and fast.)
1. Some names form a sequence. Use numbers in these names, for example, PathNode0,PathNode1. Always start with 0, not 1.
1. Do not use numbers for things that don't form a sequence. For example, Bird0, Bird1, Bird2 should be Flamingo, Eagle, Swallow.
1. Prefix temporary objects with a double underscore \_\_Player_Backup.
#### Naming Different Aspects of the Same Thing
Use underscores between the core name, and the thing that describes the aspect. For instance:
* GUI buttons states: EnterButton_Active, EnterButton_Inactive
* Textures: DarkVampire_Diffuse, DarkVampire_Normalmap
* Skybox: JungleSky_Top, JungleSky_North
* LOD Groups: DarkVampire_LOD0, DarkVampire_LOD1
Do not use this convention just to distinguish between different types of items, for instance Rock_Small, Rock_Large should be SmallRock, LargeRock.
(stolen from http://www.glenstevens.ca/unity3d-best-practices/)