Skip to content

Programmer Guide

mastercoms edited this page Jan 19, 2022 · 3 revisions

Code style

We generally use Epic's with a few exceptions [LINK REDACTED].

Part of our code style is enforced by our clang format file, so make sure your IDE has support for that.

Documentation

This project features a full documentation system, complete with diagrams and full class/function documentation. Documentation of your own code is heavily encouraged. You can use Javadoc syntax to comment header file functions, fields and classes/structs. Additionally, you can document overall systems by creating/editing markdown files in the Documentation/md folder. Both of these are used by Doxygen in our build pipeline to generate documentation which you can view by running OpenDocs.bat.

Contribution workflow

As a programming team, we've seen that developers often excel with different contribution workflows. To give our team the flexibility and choice they need to do well, we offer two forms of development: trunk-based development and feature branches.

Trunk branch

This workflow scheme is used when you want to drop in some quick code or a contribution which should be largely working (compiles, and doesn't cause major issues). It gives you the convenience of being able to contribute without the overhead or maintenance cost of your own branch, which is extremely useful if your availability is more sporadic. You can read more about the trunk based development concept here: https://trunkbaseddevelopment.com/

  1. Switch to the trunk branch: git switch trunk.
  2. Code!
  3. Add your files using git add, or add all files with git add -A ..
  4. Commit with git commit -m "<commit message>". You can leave off the end quote and press enter for multi-line. Add the end quote at the end of line and enter to finish the commit message.
  5. Push your changes with git push.
  6. When you work on your branch again, make sure to UpdateProject.bat to get the latest changes.

Feature branches

This workflow scheme is used for when you have a longer feature which can't be ready for the faster release pace of trunk, or when you can drive feature development and branch upkeep on your own. You can read more about the feature branching concept here: https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow

  1. Branch main with a branch name of the format code/feature-or-bug-fix-name: git switch -c <branch-name>
  2. Push your new branch, linking it to the remote: git push -u origin <branch-name>.
  3. Create a WIP pull request for your new branch. More info about pull requests below.
  4. Code!
  5. Add your files using git add, or add all files with git add -A ..
  6. Commit with git commit -m "<commit message>". You can leave off the end quote and press enter for multi-line. Add the end quote at the end of line and enter to finish the commit message.
  7. Push your changes with git push.
  8. When you work on your branch again, make sure to git pup to update your branch to the latest changes. After that, run UpdateProject.bat to do misc project updates.

Pull Requests

If you are still working on your branch, please prefix your pull request with WIP: . When it is done, remove the WIP status.

Resolving conflicts

Sometimes when you rebase, there will be conflicts. You can resolve text file conflicts easily, but you'll have to manually checkout LFS files with conflicts and compare them: https://github.blog/2018-11-02-git-lfs-v260/#new-git-lfs-checkout-options

Note that in a rebase, "ours" is the branch you are rebasing onto, and "theirs" is the branch you are replaying. So commonly, "ours" will be origin/main and "theirs" will be your branch.

Git Aliases

We have a number of Git aliases to do common tasks:

  • git fm: fetches latest origin main branch
  • git ro: rebases onto origin main branch
  • git pf: push --force-with lease. This command does a force push, but with a lease which checks for commit integrity.
  • git up: fm and ro
  • git pup: up and pf
  • git send: updates tracking for Source folder (adds, deletes, renames), refreshes already tracked files in all folders and pushes.
  • git s: short form of status
  • git state: shows Git LFS file status in addition to git s
  • git lard: shows the 40 biggest files in the repo
  • git last: shows the last commit
  • git uncommit: undos your last commit, but keeps your changes. You can't use this command on a protected branch if you have already pushed the commit to it.
  • git tree: shows the history in tree form
  • git force-verify: verifies the state of the repository

Commit message format

<type>(<scope>): <subject>

[body]

[footer]

A commit type is a required prefix on the subject with the following options::

  • feat: a new feature
  • fix: a bug fix
  • opt: optimization
  • docs: a change to docs or comments
  • style: style changes to the code that do not actually change the result
  • refactor: organizational/structural adjustments to code, like renaming a variable
  • test: anything to do with tests
  • chore: any repo maintenance, build config changes

Commit scope is also a required classifier which describes the system that you changed. It could be, but not limited to, the following:

  • weapons
  • render
  • config
  • ai
  • infrastructure
  • core etc.

The commit message subject is an imperative, present-tense statement that describes the change in 50 characters or less.

The optional commit message body, like the subject, is imperative and present-tense that is more detailed explanatory text. You should try to wrap your messages to 72 characters per line, because of how git formats things. You may also use a bulleted list as a summary of changes if you don't want to write it in paragraphs.

Finally, the commit footer. This is optional and should be reserved for linking commits to issue tracker issues (ex. Fixes #AT-23), and documenting breaking changes or additional required steps for developers. These warnings should be labeled with "BREAKING CHANGE:"

IDE set up

We recommend Visual Studio 2022 with at least the following installer settings:

  • Game Development with C++ workload
  • Unreal Engine Installer
  • Nuget Package Manager
  • MSBuild
  • Windows 10 SDK (latest version)

You may also want the following optional components:

  • C++ profiling tools
  • IntelliTrace
  • IntelliCode
  • AddressSanitizer

Alternatively, you can import (Visual Studio Installer > More > Import configuration) our .vsconfig LINK REDACTED. Make sure to rename the file to .vsconfig before trying to import.

Clang Format

We use clang-format for formatting. To enable clang-format support on your Visual Studio, follow the settings panel as "Options -> Text Editor -> C/C++ -> Formatting" and select "Enable ClangFormat support"

For a smoother experience with formatting, you will want to use these settings: visual studio formatting options

And, optionally, this extension to format on save: https://marketplace.visualstudio.com/items?itemName=mynkow.FormatdocumentonSave

Note that a custom clang-format.exe is used. You must install Clang 13.0.0 for support for the latest formatting features.

Include style

  • Use the shortest path for includes, instead of using fully qualified file paths
  • Order your includes like this

.h files:

#include "CoreMinimal.h"

#include "ParentClassInCaseOfInheiritance.h"
#include "InterfaceInCaseOfInheiritance.h"

#include "EngineDependency.h"

#include "PBDependency.h"

#include "PBClass.generated.h

Use forward declaration as much as possible, instead of including new header files. This is to reduce compile times and linking when cpp classes include other header files but don't necessarily need to include all the class definitions that are in the header file.

.cpp files:

#include "PBClass.h"

#include "UnrealEngineClassA.h"
#include "ThirdPartyClassA.h"
#include "UnrealEngineClassB.h"
#include "ThirdPartyClassB.h"

#include "PBOtherClassA.h"
#include "PBOtherClassB.h"

Enable Visual Studio IntelliCode

You can get AI assistance while you code to improve productivity and code quality! You can install IntelliCode from the Visual Studio Marketplace

We also recommend Resharper C++ or VisualAssistX.

Generate the solution file

  1. Right click on the ProjectBorealis.uproject file in your pb repo folder.
  2. Click Generate Visual Studio project files
  3. When launching the solution for the first time, you may be prompted to upgrade your SDK and compiler versions. Select latest installed Windows 10 SDK and compiler in your system.
  4. Select ProjectBorealis as the StartUp project: Set as StartUp Project

You must regenerate the solution file every time the engine updates. You also may have to regenerate it if other programmers remove or create source files.

Enable Unreal Engine 4 VS settings

If you haven't already done so, you can set up VS extension for UE4 by following these guides if you wish:

https://docs.unrealengine.com/en-us/Programming/Development/VisualStudioSetup

https://docs.unrealengine.com/en-us/Programming/Development/VisualStudioSetup/UnrealVS

Linux Cross Compilation support

If you need to compile Linux binaries on Windows, you will have to set up cross compilation. That's not a requirement at the moment. https://docs.unrealengine.com/en-us/Platforms/Linux/GettingStarted

Unreal Live Coding

You can now change C++ in real time while the game is running. Just enable live coding and press Ctrl+Alt+F11 at any time, even when the game is running to recompile.

Live coding currently does not support code structure updates (header file additions/removals).

RenderDoc

If you want to debug graphics, download RenderDoc, which our project has integrated support for: https://renderdoc.org/builds

GitHub CLI

To help with managing GitHub, you can use the GitHub CLI to run common GitHub tasks from the command line.

Missing or Out of Date Modules Prompt

In our engine, Unreal Build Tool by default will not attempt to build missing or mismatched modules (window that says Would you like to rebuild them now? Yes/No). You can change this behavior by setting the following in Saved/Config/Windows/EditorPerProjectUserSettings.ini:

[/Script/UnrealEd.EditorLoadingSavingSettings]
bAlwaysSkipCompile=False

This will change the behavior to instead of failing automatically, build the modules without any prompting. If it fails, it will prompt you to try building in your IDE, or look at logs.

Clone this wiki locally