-
Notifications
You must be signed in to change notification settings - Fork 121
Coding conventions
When contributing to the Augustus source, please follow the code style used in the project. Formatting conventions will be strictly enforced in pull requests to keep the code-base uniform. Don't worry about getting them all right the first time, just open a pull request, and if anything needs to change we'll kindly point that out. Code conventions and wiki page originally written by Bianca, and used with her permission.
For formatting, follow these rules, which are mostly the K&R style:
- Indent by 4 spaces
- For functions, opening and closing braces go on their own line
- For statements within functions: opening brace goes on the same line as the
if
,for
orwhile
statement - Braces are mandatory, even for blocks that are only 1 statement
- One space is required between
if
, etc and their opening parenthesis, and between the closing parenthesis and the opening brace - Switch/case statements: indent each
case
by 4 spaces, further indent the code within acase
block by another 4 spaces - Pointer variable declaration: the
*
goes next to the variable. Example: usebuilding *b;
, notbuilding* b;
- Always end the file with a new line
- Keep line length to 120 characters maximum, break up longer lines to multiple lines in positions where it's logical. Indent the continuation line(s) by 4 spaces.
The content of a C file is sorted in the following order, with a blank line between each group:
- Include of the corresponding header, without any path prefixes
- Includes of other files from the project using double quotes, using their full path starting relative to
src
, sorted alphabetically - Includes of external headers, sorted alphabetically
- Constants declared using
#define
- Constants/arrays/etc declared using
static const
- Static function declarations
- Static file variables. For UI-related files, first define the buttons, then the generic
data
container for other variables - Functions, ordered by usage. Prefer to put static functions above where they're first used
For UI window files, keep to the following order:
- Init function, if necessary
- Background draw function and related helper functions
- Foreground draw function and related helper functions
- Input handling functions and related helper functions
- Input button click handlers
- The
show
function
Use snake_case
for everything. For constants, either #define
or const
, use CAPITAL_SNAKE_CASE
to indicate they're constants.
Public functions should contain the file's location in the first part of their name to make it easy to find them. For example, the function game_tick_run()
lives in src/game/tick.c
.
Static function should NOT contain the file's location and should be given an appropriate name for what they do.
Use descriptive names, we're not on a character budget. Keep single-letter variable to a minimum. Allowed usages include:
-
i
,j
as loop variable infor
loops -
x
andy
for position variables -
b
for a pointer to a building struct -
f
for a pointer to a figure struct -
m
for a pointer to a formation (mob) struct or a mouse struct -
t
for a pointer to a touch struct -
c
for a pointer to a tooltip context struct
Group file-scoped primitive variables together in an anonymous data
struct so when using them it's clear they're global and not function-scoped. Example:
static struct {
int num_legions;
int focus_button_id;
} data;
- Try to keep the UI and game logic code as separate as possible. Ideally there should be no
#include
to eitherwindow/
orwidget/
files in any of the other files, but it's not always possible. - Do not references any of the SDL functions in the game's code outside of the
platform/
directory. This ensures that the core of the game can run without external libraries (for testing, for example), and it doesn't tie the project to SDL. If you really need to call something provided by SDL, create a function ingame/system.h
and put the implementation in one of the files in theplatform/
directory. - Keep the code free from compiler warnings where possible.