Languages Used
All game code is written to target C# 8.0. Auxiliary tools are written to target Python 3 or Unix shell.
C# Style Guide
The C# style guide is largely based on the Google Java Style Guide. Unless specified otherwise, do what the Google Java style guide recommends. Differences, or particular points worth additional note, are listed in the sections below.
Whitespace characters
Spaces only. No tabs. Manually indenting things to make things line up nicely is fine.
Braces & blocks
Each new block is indented by two spaces.
We follow Google-style (K&R) brace & block structure, like this:
if (foo) {
bar;
} else {
blah;
}
rather than the more-common C# style which looks something like this:
if (foo)
{
bar;
}
else
{
blah;
}
Braces are always used where optional, such as single-line if/while statements.
Line Length
Maximum line length is 100 characters. Exception: Levels.cs
(and similar files that are closer to data than code) can have lines of any length.
If a line is too long, prefer to line-wrap it at a higher syntactic level (as the Google Java guide suggests). When a line is broken at an operator, put the line-break after the operator (which is the opposite of what the Google Java guide suggests.)
Continuation lines should be indented by at least 4 spaces.
Example:
if (LongMethodName() && reasonablyLengthyLocalVariable &&
SomeOtherThing() {
DoSomething();
}
If a URL is too long to fit on a single line, make sure it's on a line by itself after a //-style comment, like:
// Good background reading, eventually:
// https://gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php
Names
Methods & functions are named in UpperCamelCase
: with an initial capital letter, as is common in most C# code. So are public fields of classes and structs (including properties). This differs from the Google Java style, which would name such things in lowerCamelCase
.
Constants (fields tagged with the const
keyword) are named in CONSTANT_CASE
: all uppercase, with an underscore between each word.
We generally follow Google's rules for treating acronyms as though they are a single word with only an initial capital letter (FpsCounter
, not FPSCounter
), with the exception that if a name is entirely an acronym, it stays entirely in uppercase (AABB
, not Aabb
). Once it's incorporated into a longer identifier by smooshing it together with some other word, it loses the all-caps treatment (AabbList
, not AABBList
).
Words in identifier names should be written out in full, with the following explicit exceptions which may be abbreviated:
pos
forposition
rect
forrectangle
deg
andrad
fordegrees
andradians
bg
forbackground
Namespaces
All code is in namespace SemiColinGames
. There are no sub-namespaces, with the exception of test code, which goes in namespace SemiColinGames.Tests
.
Source files & class names
Unlike in Java, source files in C# may contain more than one top-level class. It is fine to group multiple closely-related classes or structs into a single file, if it makes sense to do so.
If a file contains only a single class, the filename should match the name of that class.
Extension Methods
All definitions of extension methods must be in the file ExtensionMethods.cs
.
Type Casting
Casts shouldn't be used unless needed, but if they are necessary, they look like this:
float f = (float) someInt;
Numeric Literals
A floating-point literal between 0 and 1 always has a leading 0 before the decimal point, like this: float f = 0.1f;
.
A floating-point literal with no fractional part is preferably written with a ".0" suffix, like this: float f = 42.0f
, but it's not a strict requirement.