Skip to content

Draft: New Coding Standards

ComicIronic edited this page May 21, 2016 · 10 revisions

/vg/ coding standards

Object definitions

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()
    ...

Variables and procs

Language

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.

Types and casting

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 ..

Variable definitions.

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

Proc parameters.

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(...)

Defines: magic numbers and bare strings

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

World and access

'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.

Formatting

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.

Indentation & alignment

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()

(cant say I always agree with this, it's too situational to be a rule) This is good:

/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.

Spacing

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 aligned if it improves readability. However it should be aligned with spaces in this case, to prevent the alignment breaking on different tab sizes.

Proc usage

You should always use helper procs or macros instead of writing code from scratch. This improves maintainability a ton.

Systems and structure

Object-oriented programming

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