---
# System prepended metadata

title: Citadel Codebase Specifications (REQUIRED)
tags: [Guide To Contibuting]

---

###### 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")
