!x
1 if x is falsy (null, 0, or ''), 0 if it is not
!x
1 if x is falsy (null, 0, or ''), 0 if it is not
x %% y
The remainder of x divided by y
This is used to calculate fractional modulo calculations, unlike the % operator which only works on integers. It is equivalent to y * fract(x / y)
.
x && y
True value if x and y are both truthy, or the first falsy value encountered.
The return value is the last argument to be evaluated. The first falsy value from left to right will short-circuit the expression, and the rest of the expression will not be evaluated.
= FALSE && blow_up_the_world()
This code will never end up blowing up the world, as when evaluating the expression, it will stop after the first falsy value (in this case, FALSE
).
x &= y
Assigns x to the value of x & b
. It is equivalent to x = x & b
. This is often used for disabling bitflags in a bitfield.
= MY_BITFLAG // starts enabled
my_field &= ~MY_BITFLAG // now disabled
If both x and y are /lists, items in x that are not present in y will be removed.
= list("foo")
= list("bar")
a &= b
world.log << json_encode(a) // empty list!
x ** y
x to the power of y
x *= y
Assigns x to the value of x * y
. It is equivalent to x = x * y
.
++x (pre-increment), x++ (post-increment)
The pre-increment has the value of x + 1
, and adds 1 to x.
The post-increment has the value of x
, and then adds 1 to x.
= 0
world.log << ++x // 1
world.log << x++ // 1
world.log << x // 2
x += y
Assigns x to the value of x + y
. It is equivalent to x = x + y
.
x - y, or -y
If x is a:
- number, returns x
minus y
.
- list, a new list with y
removed from the contents of x
. If y
is also a list, where the contents are in both lists, they will be removed from the new list.
- matrix, and y
is a matrix, a new matrix with their components subtracted.
--x (pre-decrement), x-- (post-decrement)
The pre-decrement has the value of x - 1
, and subtracts 1 from x.
The post-decrement has the value of x
, and then subtracts 1 from x.
= 1
world.log << --x // 0
world.log << x-- // 0
world.log << x // -1
x -= y
Assigns x to the value of x - y
. It is equivalent to x = x - y
.
This is used to access the properties (procs and vars) of an object. This checks at compile time to see if the property being accessed does exist on the type of variable provided, providing build-time safety over the : (colon) operator.
= new /mob()
my_mob.name = "Barry"
This successfully compiles and does not generate a runtime, as the type is correctly cast to /mob, and the prototype in the variable is also a /mob.
my_mob.name = "Evil Barry"
This code also successfully compiles, as the type is correctly cast to /mob, which has an inherited variable called /atom/var/name. However, there is no /mob object assigned to the variable, so it will result in a runtime error.
x /= y
Assigns x to the value of x / y
. It is equivalent to x = x / y
.
This is used to access the properties of a variable that it is not necessarily cast as having. If the variable does not contain the specified property, a runtime error will occur.
= null
foo:name = "yay!"
This code compiles, however, upon execution of the code, it will error, as you cannot access the name
var of null.
The . (dot) operator works the same way to access a variable's properties, however, it will check at compile time if the type the variable is cast as contains this property. This is preferred behavior - it is easier to catch errors in the compiler than at runtime.
x < y
1 if x is lesser than y, 0 otherwise
If both x
and y
are strings, they are compared case sensitively - see sortTextEx().
x <= y
1 if x is lesser or equal to y, 0 otherwise
If both x
and y
are strings, they are compared case sensitively - see sortTextEx().
x = y
Assigns the value of y
to the variable x
. These can be chained together:
x = y = z
Which results in x
, y
and z
containing the same value.
x > y
1 if x is greater than y, 0 otherwise
If both x
and y
are strings, they are compared case sensitively - see sortTextEx().
x >= y
1 if x is greater or equal to y, 0 otherwise
If both x
and y
are strings, they are compared case sensitively - see sortTextEx().
x ? do_when_true() : do_when_false()
If x
evaluates to a truthy value, do_when_true()
will be evaluated and returned. Otherwise, do_when_false()
will be evaluated and returned.
= pick(1, 2)
world.log << my_number == 2 ? "My number was two!" : "My number was not two."
x?.property
This is used to access the properties of an object, like the . operator. However, using this operator, if the object is null, the access does not occur, and no runtime error will happen.
// not assigned to anything, so this will be null
my_thingy?.name = "Balloon" // as it is null, no access occurs, and no runtime occurs
= new /obj()
my_other_thingy?.name = "Runtime Damian" // as it is not null, and /obj has a member called name, the variable will be updated
This behavior is identical to the ?: operator, but that operator will not check at compile time if the property does exist for the provided variable type. As such, the ?.
operator is generally preferred.
x?:property
This is used to access the properties of an object without compile time safety-checks, like the : operator. However, using this operator, if the object is null, the access does not occur, and no runtime error will happen.
// not assigned to anything, so this will be null
my_thingy?:name = "Damian" // as it is null, no access occurs, and no runtime occurs
= 1 // assigned to a truthy value
my_other_thingy?:name = "Runtime Damian" // as it is not null, access does occur, and 1 does not have a name variable, so a runtime occurs
This behavior is identical to the ?. operator, but that operator will check if the property is valid for the variable's type. As such, that operator is typically preferred, as it will provide compile-time errors.
x?[y], where x is a list and y is an index/key
This is the null-safe indexing operator, where if the list is null, the indexing operation will not occur.
= list("foo", "bar")
world.log << my_list?[1] // "foo"
world.log << my_list?[1] // nothing!
If there is an expression on the right hand side of the operator to be evaluated and the list is null, the expression will not be evaluated. This will only take place if the list can be indexed.
my_nonexistent_list?[1] = do_something() // the proc will not be called here
my_list?[1] = do_something() // but it will be called here
list[x]
This is used to access the element of lists with a given key or index.
= list("foo")
world.log << my_list[1] // "foo"
= list("key" = "bar")
world.log << my_other_list["key"] // "bar"
x in list
1 if x is in list, 0 otherwise
This is a null-safe way of checking if an item is in a list, unlike /list/proc/Find(), which will runtime error if the list is not defined.
To check if an item is not in a given list, you can check !(item in list)
. This is distinct from checking (!item in list)
, which would coerce item into 0 or 1, and check if 0 or 1 is in the list.
x || y
True value if either x or y are truthy, or the last falsy value encountered.
The return value is the last argument to be evaluated. The first truthy value from left to right will short-circuit the expression, and the rest of the expression will not be evaluated.
= TRUE && launch_the_missiles()
The missiles will never be launched, as the expression will short-circuit after evaluating the first truthy value (in this case, TRUE
).
~x
The bitwise complement/binary NOT of 'x'.
/matrix
does not support the usage of the binary NOT operator.x ~! y
1 if x and y are not equivalent, 0 otherwise
Equivalence is a less strict version of equality - see the ~= operator.
To check two items are not equal, use !=.