Code Convention - GammaStation/Gamma-Station GitHub Wiki

Введение

Code Convention - свод несложных правил по оформлению кода. Его наличие подразумевает, что все кто вносят свои изменения, с ним соглашаются и руководствуются им в полной мере. Обязательно прочтите всю статью, если зашли сюда в первый раз. Это очень важно.

В случае если что-то не было здесь оговорено, вы можете уточнить этот момент в конфе. Хотя скорее всего это значит, что в том, что вас интересует вы вольны думать самостоятельно.

Пробелы и отступы

Блоки кода

В качестве отступов для компилируемых блоков кода используются только табы. Если код относится к комментарию (то есть для примера), то выравнивать рекомендуется пробелами.

Процедуры и функции

Между вызовом процедуры/функции и скобками не должно быть пробела.

Плохо:
/proc/foo()
	return function (1)

Хорошо:
/proc/foo()
	return function(1)

Дабы было проще искать упоминания этой функции поиском.

Операторы управления (if, while, for и т.д.)

Не должны писаться одной строкой. Иногда, если так действительно будет лучше, допускается однострочные switch и else if конструкции.

Плохо:
if(something) return TRUE

for(var/i in something) i.foo()

Хорошо:
if(something)
	return TRUE

for(var/i in something)
	i.foo()

Допустимо:
switch(x)
	if(case_1) foo()
	if(case_2) return FALSE

Все остальные операторы (+, -, =, &&, || и т.д.)

Один пробел перед оператором и один пробел после. Исключение - побитовые. Пробелы при их использовании вставляйте на своё усмотрение.

Плохо:
var/a=1
var/b   = 2
var/c =a+b

Хорошо:
var/a = 1
var/b = 2
var/c = a + b

Скобки и запятые

Следуйте единому формату. Так или иначе пробел после запятой - обязателен.

Плохо:
list( 1,2, 3, 4 ,5)

Хорошо:
list(1, 2, 3, 4, 5)

Допустимо:
list( 1 , 2 , 3 , 4 , 5 )

Комментарии

Форматирование только через пробелы. Обратите внимание на выравнивание.

Плохо:
#define A "something"		//	Это что-то.
#define B "anything"	//Это что угодно.

Хорошо:
#define A "something"  // Это что-то.
#define B "anything"   // Это что угодно.

Выравнивание новых строк

Например, при объявлении элементов списка - преимущественно пробелами.

Плохо:
list(1, 2, 3,
	4, 5, 6)

Хорошо:
list(1, 2, 3
     4, 5, 6)

Допустимо:
list(
	1, 2, 3,
	4, 5, 6
)

Описание путей

Абсолютные

Все пути в обязательном порядке должны быть абсолютными.

Плохо:
obj
	var
		varname1 = 0
		varname2
	proc
		proc_name()
			code
	item
		weapon
			name = "Weapon"
			proc
				proc_name2()
					..()
					code

Хорошо:
/obj
	var/varname1 = 0
	var/varname2

/obj/proc/proc_name()
	code

/obj/item/weapon
	name = "Weapon"

/obj/item/weapon/proc/proc_name2()
	..()
	code

Должны начинаться с /

Плохо:
mob/living

Хорошо:
/mob/living

Так как, путь не начинающийся со слэша компилятором будет считаться как относительный, и если где-либо будет путь /foo/mob/living, он может присвоить все переменные класса /mob/living(который мы написали без слэша), классу соответствующему этому пути.

Не описываются через текстовую строку

Плохо:
var/path = "/obj/item/something"

Хорошо:
var/path = /obj/item/something

Пути не описываются через текстовую строку, в связи с тем, что при компиляции, компилятор не обратит внимание на несуществующий путь в текстовой строке, и не выдаст ошибку. У этого могут быть последствия, в случае, если классы будут удаляться, или их путь будет меняться, можно просто забыть поменять его во всех местах.

Работа с кодом

К прочтению:

  • [Работа с чатом]
  • [Работа с реалтайм событиями]

Объявление аргументов в процедурах

Не должно быть конструкций типа var/ и as ...

Плохо:
/proc/foo(var/atom/A as area|turf|obj|mob)

Хорошо:
/proc/foo(atom/A)

Оператор :

Использование запрещено. Всегда приводите объект к нужному вам типу.

Плохо:
/proc/foo(atom/A)
	return A:some_var

Хорошо:
/proc/foo(atom/A)
	var/obj/O = A
	return O.some_var

Ведь данный оператор запускает поиск по всем переменным и сверяется, есть ли такая переменная вообще у интересующего нас пути.

Магические числа

Если не знаете что это, то прочитайте эту статью Магическое число (программирование). Соответственно их быть не должно. Используйте дефайны или константные переменные.

Плохо:
/proc/foo(variable)
	switch(variable)
		if(1)
			do something
		if(2)
			return

Хорошо:
#define CASE_1 1
#define CASE_2 2

/proc/foo(variable)
	switch(variable)
		if(CASE_1)
			do something
		if(CASE_2)
			return

#undef CASE_1
#undef CASE_2

Булевский тип

Вместо 1 и 0 используйте TRUE и FALSE соответственно.

Использование src

Используйте только тогда, когда это необходимо.

Плохо:
/mob/some/class/proc/foo()
	src.some_var = some_value
	src.another_var = another_value

Хорошо:
/mob/some/class/proc/foo()
	some_var = some_value
	another_var = another_value

Пример необходимого использования:
/mob/some/class/proc/foo(some_var, another_var)
	src.some_var = some_var
	src.another_var =  another_var

Особенности BYOND

Использование spawn()

Не используйте. О причинах читайте тут [Работа с реалтайм событиями].

Работа с циклами (black magic)

Цикл вида for(var/i = 1; i <= const_val; i++) должен быть записан в следующей форме for(var/i in 1 to const_val). Причина: второй цикл работает быстрее. Почему? Хороший вопрос, стоит задать его кодерам BYOND. У обоих видов одинаковое поведение, но у второго есть нюансы. to тоже самое, что и <=, соответственно чтобы было < нужно сделать for(var/i in 1 to const_val - 1). Ещё важный момент - const_val переменная не должна быть изменена во время цикла. То есть если вы делаете проход по списку, который изменяется внутри цикла, а const_val размер списка, то вам нужно использовать классический, первый, вариант.