-
Notifications
You must be signed in to change notification settings - Fork 541
Draft: New Coding Standards
All paths should be absolute, up to variable 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 = TRUE
attackby()
...
proc
off()
...
The same example, but then absolutely pathed:
/obj/machinery/apc
var/on = TRUE
/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.
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 defining variables in procs with the same name as variables on the src
object is allowed, this should not be done because it makes the code harder to need and understand.
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(...)
When SS13 was initially decompiled, the decompiler used made all integer numbers end in .0
due to a bug. This has blindly been taken over by oldcode and is prevalent around the code. Integers should never end in .0
.
When a value should only be used as a boolean, the native TRUE
and FALSE
macros should be used instead of the more common 1
and 0
, respectively.
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
All HTML code needs to be HTML5 and W3C compliant..
Alongside the above, there are also some other standards we enforce:
- HTML tags must be fully lowercase.
- No spaces around the
=
sign in an element's attributes. - There must always be single quotes around the values of attributes.
- Using the
style
attribute is not allowed.
While BYOND defaults to IE 7 for interfaces, it is possible to bump this up to the highest IE version on the client's system (including Edge on Windows 10) by adding the following meta tag: <meta http-equiv="X-UA-Compatible" content="IE=edge" />
.
Because the effect of this is based on the user's system, IE 8 is the highest IE version that can be guaranteed, because higher IE versions do not work on Windows XP, which is the minimum OS we support.
All HTML code must be usable in Internet Explorer 8. Usable means that no loss of functionality incurs on IE8. Appearance-only things do not necessarily need to work in IE8.
While BYOND itself uses Windows-1252, you can send UTF-8 to the client in HTML interfaces if the charset is specified in the HTML. When you write DM code with a special, UTF-8 character, BYOND actually reads a garbled mess, however because it sends the text to the client literally, IE is still able to parse this as Unicode.
To get to the point: all HTML interfaces must specify UTF-8 as charset in the HTML (<meta http-equiv="content-type" charset="utf-8" />
). The code files that generate the interface must be encoded as UTF-8.
Note: While this is nice, chat and UI frameworks like NanoUI and HTML Interface do not support this, and while you should still encode the file as UTF-8, you should not use any characters which are not in Windows-1252 or have a different position in Windows-1252 from UTF-8. See this table for reference.