-
Notifications
You must be signed in to change notification settings - Fork 541
Draft: New Coding Standards
All paths should be absolute, up to var definitions: BYOND permits relative pathing, however this is worse for readability and make searching for specific procs or variables much harder.
An example of relative pathing:
obj
machinery
apc
var
on = 1
attackby()
...
proc
off()
...
The same example, but then relatively pathed:
/obj/machinery/apc
var/on = 1
/obj/machinery/apc/attackby()
...
/obj/machinery/apc/proc/off()
...
All proc and variable names should be in American English, this is to be consistent with BYOND which also uses American English (variables like color, for example). This includes s/z differences.
The runtime operator :
is never permitted for accessing vars or procs on a variable, even if preceeded by a typecheck. You should always cast to the proper type after the typecheck, and then access vars and procs normally, using .
.
All variable definitions should use the most specific path possible:
This: var/obj/A
is worse than var/obj/machinery/A
when the code only expects a machine.
Constant variables (/const
) should never be used, use #define
s instead.
Temporary variables (/tmp
) should be used where applicable. (Example: a machine variable which references the mob that is currently using it.)
When making a variable a list which contains only a single type of object, the variable type should correctly represent this. (var/list/obj/machinery/machines
vs var/list/machines
)
While using var/
is optional in proc parameters, it should be used anyways. The rules for var typing also apply to proc parameters: types should be as specific as possible.
For ellipses (procs which take any amount of arguments), one should use ...
in the proc parameters like this: /proc/myproc(...)
All values which appear in code repeatedly and have to be the same in every instance should be replaced instead with a string or number define.
/obj/item/stamp
var/stamp_stage = 0
/obj/item/stamp/proc/stamp()
if(stamp_stage == 0)
stamp_stage = 2
Should instead be
#define UNSTAMPED 0
#define STAMPED 2
/obj/item/stamp
var/stamp_stage = UNSTAMPED
/obj/item/stamp/proc/stamp()
if(stamp_stage == UNSTAMPED)
stamp_stage = STAMPED
'in world' should always be avoided. Any requirement to loop through all objects fulfilling a criteria in the world should be done by a global list which objects add themselves to and remove themselves from.
Accessing global variables should use global.
to make it more clear that the variable is global.
You should never use src.
when accessing variables or procs on the src
object, as it is always implied, unless there is a code reason, such as variable ambiguity.
All statements, conditionals, and loops should be on their own lines. Especially long conditionals should be broken up by the \ separator and put onto multiple lines for readability. A good guide is no more than 4 conditional statements per line.
No usage of labels and goto
. Labelled loops are fine, but discouraged.
You should try to avoid indenting code as much as possible. This is bad:
/obj/myobject/attackby(var/obj/item/W, var/mob/user)
if (istype(W, /obj/item/device/multitool))
thing()
else
otherthing()
This is better:
/obj/myobject/attackby(var/obj/item/W, var/mob/user)
if (istype(W, /obj/item/device/multitool))
thing()
return
otherthing()
All indentation should be done by hard tabs. This means the tab character should be used, not 4 spaces.
There should be a space between all binary (=, ==, <(=), >(=), !=) and trinary (?:) operators and their operands. There should not be a spacing between unary operators (!) and their operands.
There should also be a space between control flow keywords and their parenthesis: if (var)
Code should be manually aligned if it improves readability. However it should be aligned with spaces in this case, to prevent the alignment breaking on different tab sizes. This only applies to decorative alignment: indentation is done by tabs as above.
While the semicolon is a legal line terminator for DM, it is entirely redundant. Lines should not end with a semicolon.
You should always use helper procs or macros instead of writing code from scratch. This improves maintainability a ton.
All systems and implementations should strive to be designed with Byond's object-oriented language in mind. The following things should be avoided:
Type lists and hard-coded type checking for behaviour in general systems
Type checks on src - this is a clear sign you've gone wrong