###### tags: `Guide To Contibuting`
# Citadel Codebase Specifications (REQUIRED)
## For an up to date list, check [CONTRIBUTING.md](https://github.com/Citadel-Station-13/Citadel-Station-13/CONTRIBUTING.md) in our codebase, .github folder.
## Specifications
You are expected to follow these specifications in order to make everyone's lives easier. It'll save both your time and ours, by making sure you don't have to make any changes and we don't have to ask you to. Thank you for reading this section!
<!-- stolen from tg, we should have this, because clean code good -->
### All BYOND paths must contain the full path
(i.e. absolute pathing)
DM will allow you nest almost any type keyword into a block, such as:
```DM
datum
datum1
var
varname1 = 1
varname2
static
varname3
varname4
proc
proc1()
code
proc2()
code
datum2
varname1 = 0
proc
proc3()
code
proc2()
..()
code
```
The use of this is not allowed in this project as it makes finding definitions via full text searching next to impossible. The only exception is the variables of an object may be nested to the object, but must not nest further.
The previous code made compliant:
```DM
/datum/datum1
var/varname1
var/varname2
var/static/varname3
var/static/varname4
/datum/datum1/proc/proc1()
code
/datum/datum1/proc/proc2()
code
/datum/datum1/datum2
varname1 = 0
/datum/datum1/datum2/proc/proc3()
code
/datum/datum1/datum2/proc2()
..()
code
```
### Type paths must begin with a /
eg: `/datum/thing`, not `datum/thing`
### Datum type paths must began with "datum"
In DM, this is optional, but omitting it makes finding definitions harder.
### Do not use text/string based type paths
It is rarely allowed to put type paths in a text format, as there are no compile errors if the type path no longer exists. Here is an example:
```DM
//Good
var/path_type = /obj/item/baseball_bat
//Bad
var/path_type = "/obj/item/baseball_bat"
```
### Tabs, not spaces
You must use tabs to indent your code, NOT SPACES.
(You may use spaces to align something, but you should tab to the block level first, then add the remaining spaces)
### No magic numbers or strings
This means stuff like having a "mode" variable for an object set to "1" or "2" with no clear indicator of what that means. Make these #defines with a name that more clearly states what it's for. For instance:
```DM
/datum/proc/do_the_thing(thing_to_do)
switch(thing_to_do)
if(1)
(...)
if(2)
(...)
```
There's no indication of what "1" and "2" mean! Instead, you'd do something like this:
```DM
#define DO_THE_THING_REALLY_HARD 1
#define DO_THE_THING_EFFICIENTLY 2
/datum/proc/do_the_thing(thing_to_do)
switch(thing_to_do)
if(DO_THE_THING_REALLY_HARD)
(...)
if(DO_THE_THING_EFFICIENTLY)
(...)
```
This is clearer and enhances readability of your code! Get used to doing it!
### Use our time defines
The codebase contains some defines which will automatically multiply a number by the correct amount to get a number in deciseconds. Using these is preffered over using a literal amount in deciseconds.
The defines are as follows:
* SECONDS
* MINUTES
* HOURS
This is bad:
````DM
/datum/datum1/proc/proc1()
if(do_after(mob, 15))
mob.dothing()
````
This is good:
````DM
/datum/datum1/proc/proc1()
if(do_after(mob, 1.5 SECONDS))
mob.dothing()
````
### Operators
#### Spacing
(this is not strictly enforced, but more a guideline for readability's sake)
* Operators that should be separated by spaces
* Boolean and logic operators like &&, || <, >, ==, etc (but not !)
* Bitwise AND &
* Argument separator operators like , (and ; when used in a forloop)
* Assignment operators like = or += or the like
* Operators that should not be separated by spaces
* Bitwise OR |
* Access operators like . and :
* Parentheses ()
* logical not !
Math operators like +, -, /, *, etc are up in the air, just choose which version looks more readable.
#### Use
* Bitwise AND - '&'
* Should be written as ```bitfield & bitflag``` NEVER ```bitflag & bitfield```, both are valid, but the latter is confusing and nonstandard.
* Associated lists declarations must have their key value quoted if it's a string
* WRONG: list(a = "b")
* RIGHT: list("a" = "b")