]> de.git.xonotic.org Git - xonotic/xonotic.wiki.git/blobdiff - Introduction_to_QuakeC.md
textile to gh-markdown (pandoc conversion)
[xonotic/xonotic.wiki.git] / Introduction_to_QuakeC.md
index 88d5afa742cf63c15ace4355b393f91823d3b4b0..a9d79f8d035d0f7e01daea7642d62f955f0c6108 100644 (file)
-h1. QuakeC
+QuakeC
+======
 
-{{>toc}}
+{{\>toc}}
 
-h2. Article TODO
+Article TODO
+------------
 
-* expand explanations
+-   expand explanations
 
-h2. About QuakeC
+About QuakeC
+------------
 
 QuakeC is a very simplified dialect of the well-known C programming language, and is used by the Quake I engine and its derivatives. Xonotic uses the FTEQCC dialect of QuakeC, so only this dialect will be described (as well as some common extensions among Quake engines).
 
-h2. Example code
+Example code
+------------
 
 To see what QuakeC looks like, here is a piece of example code:
 
-<pre><code class="c">
-  // needed declarations:
-  float vlen(vector v) = #12;
-  entity nextent(entity e) = #47;
-  .string classname;
-  .vector origin;
-  // ...
-  entity findchain(.string fld, string match)
-  {
-    entity first, prev;
-    entity e;
-    first = prev = world;
-    for(e = world; (e = nextent(e)); ++e)
-      if(e.fld == match)
+      // needed declarations:
+      float vlen(vector v) = #12;
+      entity nextent(entity e) = #47;
+      .string classname;
+      .vector origin;
+      // ...
+      entity findchain(.string fld, string match)
       {
-        e.chain = world;
-        if(prev)
-          prev.chain = e;
-        else
-          first = e;
-        prev = e;
+        entity first, prev;
+        entity e;
+        first = prev = world;
+        for(e = world; (e = nextent(e)); ++e)
+          if(e.fld == match)
+          {
+            e.chain = world;
+            if(prev)
+              prev.chain = e;
+            else
+              first = e;
+            prev = e;
+          }
+        return first;
       }
-    return first;
-  }
-  // ...
-  entity findnearestspawn(vector v)
-  {
-    entity nearest;
-    entity e;
-    for(e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
-      if(!nearest)
-        nearest = e;
-      else if(vlen(e.origin - v) < vlen(nearest.origin - v))
-        nearest = e;
-    return nearest;
-  }
-</code></pre>
-*Note:* _findchain_ is implemented in QuakeC for demonstration purposes only so one can see how to build a linked list, as this function is already built in to the engine and can be used directly
-
-h2. Other resources
+      // ...
+      entity findnearestspawn(vector v)
+      {
+        entity nearest;
+        entity e;
+        for(e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
+          if(!nearest)
+            nearest = e;
+          else if(vlen(e.origin - v) < vlen(nearest.origin - v))
+            nearest = e;
+        return nearest;
+      }
+
+**Note:** *findchain* is implemented in QuakeC for demonstration purposes only so one can see how to build a linked list, as this function is already built in to the engine and can be used directly
+
+Other resources
+---------------
 
 Here is a forum on Inside3D where you can read more about QuakeC and ask questions:
-* QuakeC Forum on Inside3D: http://forums.inside3d.com/viewforum.php?f=2
-* QC Tutorial for Absolute Beginners: http://forums.inside3d.com/viewtopic.php?t=1286
+\* QuakeC Forum on Inside3D: http://forums.inside3d.com/viewforum.php?f=2
+\* QC Tutorial for Absolute Beginners: http://forums.inside3d.com/viewtopic.php?t=1286
 
 For available functions in QuakeC, look in the following places:
-* The Quakery: http://quakery.quakedev.com/qwiki/index.php/List_of_builtin_functions
-* Xonotic source: "builtins.qh":http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/builtins.qh;hb=HEAD for Quake functions, "extensions.qh":http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/extensions.qh;hb=HEAD for DarkPlaces extensions
-
+\* The Quakery: http://quakery.quakedev.com/qwiki/index.php/List\_of\_builtin\_functions
+\* Xonotic source: [builtins.qh](http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/builtins.qh;hb=HEAD) for Quake functions, [extensions.qh](http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/extensions.qh;hb=HEAD) for DarkPlaces extensions
 
-h1. Variables
+Variables
+=========
 
-h2. Declaring
+Declaring
+---------
 
 To declare a variable, the syntax is the same as in C:
 
-<pre><code class="c">
-  float i;
-</code></pre>
+      float i;
 
 However, variables cannot be initialized in their declaration for historical reasons, and trying to do so would define a constant.
 
-Whenever a variable declaration could be interpreted as something else by the compiler, the _var_ keyword helps disambiguating. For example,
+Whenever a variable declaration could be interpreted as something else by the compiler, the *var* keyword helps disambiguating. For example,
 
-<pre><code class="c">
-  float(float a, float b) myfunc;
-</code></pre>
+      float(float a, float b) myfunc;
 
 is an old-style function declaration, while
 
-<pre><code class="c">
-  var float(float a, float b) myfunc;
-</code></pre>
+      var float(float a, float b) myfunc;
 
-declares a variable of function type. An alternate and often more readable way to disambiguate variable declarations is using a _typedef_, like so:
+declares a variable of function type. An alternate and often more readable way to disambiguate variable declarations is using a *typedef*, like so:
 
-<pre><code class="c">
-  typedef float(float, float) myfunc_t;
-  myfunc_t myfunc;
-</code></pre>
+      typedef float(float, float) myfunc_t;
+      myfunc_t myfunc;
 
-h2. Scope
+Scope
+-----
 
-A variable declared in the global scope has global scope, and is visible starting from its declaration to the end of the code. The order the code is read in by the compiler is defined in the file %%progs.src%%.
+A variable declared in the global scope has global scope, and is visible starting from its declaration to the end of the code. The order the code is read in by the compiler is defined in the file %progs.src%.
 A variable declared inside a function has block scope, and is visible starting from its declaration to the end of the smallest block that contains its declaration.
 
-Some variables are declared in "sys.qh":http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/sys.qh;hb=HEAD. Their declarations or names should never be changed, as they have to match the order and names of the variables in the file file "progdefs.h":http://svn.icculus.org/twilight/trunk/darkplaces/progdefs.h?view=markup of the engine exactly, or the code won't load. The special markers _end_sys_globals_ and _end_sys_fields_ are placed to denote the end of this shared declaration section.
+Some variables are declared in [sys.qh](http://git.xonotic.org/?p=xonotic/xonotic-data.pk3dir.git;a=blob_plain;f=qcsrc/server/sys.qh;hb=HEAD). Their declarations or names should never be changed, as they have to match the order and names of the variables in the file file [progdefs.h](http://svn.icculus.org/twilight/trunk/darkplaces/progdefs.h?view=markup) of the engine exactly, or the code won’t load. The special markers *end\_sys\_globals* and *end\_sys\_fields* are placed to denote the end of this shared declaration section.
 
-h1. Types
+Types
+=====
 
-Quake only knows four elementary data types: the basic types _float_, _vector_, _string_, and the object type _entity_. Also, there is a very special type of types, _fields_, and of course _functions_. FTEQCC also adds _arrays_, although these are slow and a bit buggy. Note that there are no pointers!
+Quake only knows four elementary data types: the basic types *float*, *vector*, *string*, and the object type *entity*. Also, there is a very special type of types, *fields*, and of course *functions*. FTEQCC also adds *arrays*, although these are slow and a bit buggy. Note that there are no pointers!
 
-h2. float
+float
+-----
 
 This is the basic numeric type in QuakeC. It represents the standard 32bit floating point type as known from C. It has 23 bits of mantissa, 8 bits of exponent, and one sign bit. The numeric range goes from about 1.175e-38 to about 3.403e+38, and the number of significant decimal digits is about six.
 
-As float has 23 bits of mantissa, it can also be used to safely represent integers in the range from -16777216 to 16777216. 16777217 is the first integer _float_ can not represent.
+As float has 23 bits of mantissa, it can also be used to safely represent integers in the range from –16777216 to 16777216. 16777217 is the first integer *float* can not represent.
 
-Common functions for _float_ are especially _ceil_, _floor_ (working just like in C, rounding up/down to the next integer), and _random_, which yields a random number _r_ with _0 %%<=%% r < 1_.
+Common functions for *float* are especially *ceil*, *floor* (working just like in C, rounding up/down to the next integer), and *random*, which yields a random number *r* with *0 \<= r \< 1*.
 
-h2. vector
+vector
+------
 
-This type is basically three floats together. By declaring a _vector v_, you also create three floats _v_x_, _v_y_ and _v_z_ (note the underscore) that contain the components of the vector.
+This type is basically three floats together. By declaring a *vector v*, you also create three floats *v\_x*, *v\_y* and *v\_z* (note the underscore) that contain the components of the vector.
 
-Vectors can be used with the usual mathematical operators in the usual way used in mathematics. For example, _vector + vector_ simply returns the sum of the vectors, and _vector * float_ scales the vector by the given factor. Note however that dividing a vector by a float is NOT supported, one has to use _vector * (1 / float)_ instead. Multiplying two vectors yields their dot product of type float.
+Vectors can be used with the usual mathematical operators in the usual way used in mathematics. For example, *vector + vector* simply returns the sum of the vectors, and *vector \* float* scales the vector by the given factor. Note however that dividing a vector by a float is NOT supported, one has to use *vector \* (1 / float)* instead. Multiplying two vectors yields their dot product of type float.
 
-Common functions to be used on vectors are _vlen_ (vector length), _normalize_ (vector divided by its length, i.e. a unit vector).
+Common functions to be used on vectors are *vlen* (vector length), *normalize* (vector divided by its length, i.e. a unit vector).
 
-Vector literals are written like '1 0 0'.
-
-**COMPILER BUG:** Always use _vector = vector * float_ instead of _vector *= float_, as the latter creates incorrect code!
+Vector literals are written like ‘1 0 0’.
 
+**COMPILER BUG:** Always use *vector = vector \* float* instead of \_vector **= float\_, as the latter creates incorrect code!
 h2. string
+A *string* in QuakeC is an immutable reference to a null-terminated character string stored in the engine. It is not possible to change a character in a string, but there are various functions to create new strings:
+** **ftos** and **vtos** convert *floats* and *vectors* to strings. Their inverses are, of course, *stof* and *stov*, which parse a *string* into a *float* or a *vector*.
+
+-   **strcat** concatenates 2 to 8 strings together, as in:
+    \<pre\><code class="c">
+    strcat(“a”, “b”, “c”)==“abc”;
+    </code>\</pre\>
+
+-   **strstrofs(haystack, needle, offset)** searches for an occurrence of one string in another, as in:
+    \<pre\><code class="c">
+    strstrofs(“haystack”, “ac”, 0)==5;
+    </code>\</pre\>
+
+The offset defines from which starting position to search, and the return value is *–1* if no match is found. The offset returned is *0*-based, and to search in the whole string, a start offset of *0* would be used.
+
+-   **substring(string, startpos, length)** returns part of a string. The offset is *0*~~based here, too.
+    Note that there are different kinds of *strings*, regarding memory management:
+    \* **Temporary strings** are strings returned by built-in string handling functions such as *substring*, *strcat*. They last only for the duration of the function call from the engine. That means it is safe to return a temporary string in a function you wrote, but not to store them in global variables or objects as their storage will be overwritten soon.
+    \* **Allocated strings** are strings that are explicitly allocated. They are returned by *strzone* and persist until they are freed (using *strunzone*). Note that *strzone* does not change the string given as a parameter, but returns the newly allocated string and keeps the passed temporary string the same way! That means:
+    **** To allocate a string, do for example:
+    \<pre\><code class="c">
+    myglobal = strzone(strcat(“hello ”, “world”));
+    </code>\</pre\>
+    **** To free the string when it is no longer needed, do:
+    \<pre\><code class="c">
+    strunzone(myglobal);
+    </code>\</pre\>
+    \* **Engine-owned strings**, such as *netname*. These should be treated just like temporary strings: if you want to keep them in your own variables, *strzone* them.
+    \* **Constant strings:** A string literal like *“foo”* gets permanent storage assigned by the compiler. There is no need to *strzone* such strings.
+    \* **The null string:** A global uninitialized *string* variable has the special property that is is usually treated like the constant, empty, string *“”* (so using it does not constitute an error), but it is the only string that evaluates to FALSE in an if expression (but not in the ! operator~~ in boolean context, the string “” counts as FALSE too). As this is a useful property, Xonotic code declares such a string variable of the name *string\_null*. That means that the following patterns are commonly used for allocating strings:
+    -   Assigning to a global string variable:
+        \<pre\>
+        if(myglobal)
+         strunzone(myglobal);
+
+myglobal = strzone(…);
 
-A _string_ in QuakeC is an immutable reference to a null-terminated character string stored in the engine. It is not possible to change a character in a string, but there are various functions to create new strings:
+</pre>
+**** Freeing the global string variable:
 
-* *ftos* and *vtos* convert _floats_ and _vectors_ to strings. Their inverses are, of course, _stof_ and _stov_, which parse a _string_ into a _float_ or a _vector_.
+    if(myglobal)
+         strunzone(myglobal);
 
-* *strcat* concatenates 2 to 8 strings together, as in:
-<pre><code class="c">
-strcat("a", "b", "c")=="abc";
-</code></pre>
+    myglobal = string_null;
 
-* *strstrofs(haystack, needle, offset)* searches for an occurrence of one string in another, as in:
-<pre><code class="c">
-strstrofs("haystack", "ac", 0)==5;
-</code></pre>
+**** Checking if a global string value has been set:
 
-The offset defines from which starting position to search, and the return value is _-1_ if no match is found. The offset returned is _0_-based, and to search in the whole string, a start offset of _0_ would be used.
+    if(myglobal) {
+         value has been set;
+    }
+    else {
+         string has not yet been set;
+    }
 
-* *substring(string, startpos, length)* returns part of a string. The offset is _0_-based here, too.
+entity
+------
 
-Note that there are different kinds of _strings_, regarding memory management:
-* *Temporary strings* are strings returned by built-in string handling functions such as _substring_, _strcat_. They last only for the duration of the function call from the engine. That means it is safe to return a temporary string in a function you wrote, but not to store them in global variables or objects as their storage will be overwritten soon.
+The main object type in QuakeC is *entity*, a reference to an engine internal object. An *entity* can be imagined as a huge struct, containing many *fields*. This is the only object type in the language. However, *fields* can be added to the *entity* type by the following syntax:
 
-* *Allocated strings* are strings that are explicitly allocated. They are returned by _strzone_ and persist until they are freed (using _strunzone_). Note that _strzone_ does not change the string given as a parameter, but returns the newly allocated string and keeps the passed temporary string the same way! That means:
-** To allocate a string, do for example:
-<pre><code class="c">
-myglobal = strzone(strcat("hello ", "world"));
-</code></pre>
-** To free the string when it is no longer needed, do:
-<pre><code class="c">
-strunzone(myglobal);
-</code></pre>
+    .float myfield;
 
-* *Engine-owned strings*, such as _netname_. These should be treated just like temporary strings: if you want to keep them in your own variables, _strzone_ them.
+and then all objects *e* get a field that can be accessed like in *e.myfield*.
 
-* *Constant strings:* A string literal like _"foo"_ gets permanent storage assigned by the compiler. There is no need to _strzone_ such strings.
+The special entity *world* also doubles as the *null* reference. It can not be written to other than in the *spawnfunc\_worldspawn* function that is run when the map is loaded, and is the only entity value that counts as *false* in an *if* expression. Thus, functions that return *entities* tend to return *world* to indicate failure (e.g. *find* returns *world* to indicate no more entity can be found).
 
-* *The null string:* A global uninitialized _string_ variable has the special property that is is usually treated like the constant, empty, string _""_ (so using it does not constitute an error), but it is the only string that evaluates to FALSE in an if expression (but not in the ! operator - in boolean context, the string "" counts as FALSE too). As this is a useful property, Xonotic code declares such a string variable of the name _string_null_. That means that the following patterns are commonly used for allocating strings:
-** Assigning to a global string variable:
-<pre>
-if(myglobal)
-     strunzone(myglobal);
+If a field has not been set, it gets the usual zero value of the type when the object is created (i.e. *0* for *float*, *string\_null* for *string*, *’0 0 0’* for *vector*, and *world* for *entity*).
 
-myglobal = strzone(...);
-</pre>
-** Freeing the global string variable:
-<pre>
-if(myglobal)
-     strunzone(myglobal);
-
-myglobal = string_null;
-</pre>
-** Checking if a global string value has been set:
-<pre>
-if(myglobal) {
-     value has been set;
-}
-else {
-     string has not yet been set;
-}
-</pre>
+fields
+------
 
-h2. entity
+A reference to such a field can be stored too, in a field variable. It is declared and used like
 
-The main object type in QuakeC is _entity_, a reference to an engine internal object. An _entity_ can be imagined as a huge struct, containing many _fields_. This is the only object type in the language. However, _fields_ can be added to the _entity_ type by the following syntax:
+      .float myfield;
+      // ...
+      // and in some function:
+      var .float myfieldvar;
+      myfieldvar = myfield;
+      e.myfieldvar = 42;
 
-<pre>
-.float myfield;
-</pre>
+Field variables can be used as function parameters too - in that case you leave the *var* keyword out, as it is not needed for disambiguation.
 
-and then all objects _e_ get a field that can be accessed like in _e.myfield_.
+functions
+---------
 
-The special entity _world_ also doubles as the _null_ reference. It can not be written to other than in the _spawnfunc_worldspawn_ function that is run when the map is loaded, and is the only entity value that counts as _false_ in an _if_ expression. Thus, functions that return _entities_ tend to return _world_ to indicate failure (e.g. _find_ returns _world_ to indicate no more entity can be found).
+Functions work just like in C:
 
-If a field has not been set, it gets the usual zero value of the type when the object is created (i.e. _0_ for _float_, _string_null_ for _string_, _'0 0 0'_ for _vector_, and _world_ for _entity_).
+      float sum3(float a, float b, float c)
+      {
+        return a + b + c;
+      }
 
-h2. fields
+However, the syntax to declare function pointers is simplified:
 
-A reference to such a field can be stored too, in a field variable. It is declared and used like
-<pre>
-  .float myfield;
-  // ...
-  // and in some function:
-  var .float myfieldvar;
-  myfieldvar = myfield;
-  e.myfieldvar = 42;
-</pre>Field variables can be used as function parameters too - in that case you leave the _var_ keyword out, as it is not needed for disambiguation.
+      typedef float(float, float, float) op3func_t;
+      var float(float a, float b, float c) f;
+      op3func_t g;
+      f = sum3;
+      g = f;
+      print(ftos(g(1, 2, 3)), "\n"); // prints 6
 
-h2. functions
+Also note that the *var* keyword is used again to disambiguate from a global function declaration.
 
-Functions work just like in C:
-<pre>
-  float sum3(float a, float b, float c)
-  {
-    return a + b + c;
-  }</pre>
+In original QuakeC by iD Software, this simplified function pointer syntax also was the only way to define functions (you may still encounter this in Xonotic’s code in a few places):
 
-However, the syntax to declare function pointers is simplified:
-<pre>
-  typedef float(float, float, float) op3func_t;
-  var float(float a, float b, float c) f;
-  op3func_t g;
-  f = sum3;
-  g = f;
-  print(ftos(g(1, 2, 3)), "\n"); // prints 6
-</pre>
+      float(float a, float b) sum2 = {
+        return a + b;
+      }
 
-Also note that the _var_ keyword is used again to disambiguate from a global function declaration.
+A special kind of functions are the built-in functions, which are defined by the engine. These are imported using so-called built-in numbers, with a syntax like:
 
-In original QuakeC by iD Software, this simplified function pointer syntax also was the only way to define functions (you may still encounter this in Xonotic's code in a few places):
+      string strcat(string a, string b, ...) = #115;
 
-<pre>
-  float(float a, float b) sum2 = {
-    return a + b;
-  }
-</pre>
+void
+----
 
-A special kind of functions are the built-in functions, which are defined by the engine. These are imported using so-called built-in numbers, with a syntax like:
-<pre>
-  string strcat(string a, string b, ...) = #115;
-</pre>
+Just like in C, the *void* type is a special placeholder type to declare that a function returns nothing. However, unlike in C, it is possible to declare variables of this type, although the only purpose of this is to declare a variable name without allocating space for it. The only occasion where this is used is the special *end\_sys\_globals* and *end\_sys\_fields* marker variables.
 
-h2. void
+arrays
+------
 
-Just like in C, the _void_ type is a special placeholder type to declare that a function returns nothing. However, unlike in C, it is possible to declare variables of this type, although the only purpose of this is to declare a variable name without allocating space for it. The only occasion where this is used is the special _end_sys_globals_ and _end_sys_fields_ marker variables.
+As the QuakeC virtual machine provides no pointers or similar ways to handle arrays, array support is added by FTEQCC and very limited. Arrays can only be global, must have a fixed size (not dynamically allocated), and are a bit buggy and slow. Almost as great as in FORTRAN, except they can’t be multidimensional either!
 
-h2. arrays
+You declare arrays like in C:
 
-As the QuakeC virtual machine provides no pointers or similar ways to handle arrays, array support is added by FTEQCC and very limited. Arrays can only be global, must have a fixed size (not dynamically allocated), and are a bit buggy and slow. Almost as great as in FORTRAN, except they can't be multidimensional either!
+      #define MAX_ASSASSINS 16
+      entity assassins[MAX_ASSASSINS];
+      #define BTREE_MAX_CHILDREN 5
+      .entity btree_child[BTREE_MAX_CHILDREN];
+      #define MAX_FLOATFIELDS 3
+      var .float myfloatfields[MAX_FLOATFIELDS];
 
-You declare arrays like in C:
-<pre>
-  #define MAX_ASSASSINS 16
-  entity assassins[MAX_ASSASSINS];
-  #define BTREE_MAX_CHILDREN 5
-  .entity btree_child[BTREE_MAX_CHILDREN];
-  #define MAX_FLOATFIELDS 3
-  var .float myfloatfields[MAX_FLOATFIELDS];
-</pre>
 The former is a global array of entities and can be used the usual way:
-<pre>
-  assassins[self.assassin_index] = self;
-</pre>
+
+      assassins[self.assassin_index] = self;
+
 The middle one is a global array of (allocated and constant) entity fields and **not** a field of array type (which does not exist), so its usage looks a bit strange:
-<pre>
-for(i = 0; i < BTREE_MAX_CHILDREN; ++i)
-  self.(btree_child[i]) = world;
-</pre>
+
+    for(i = 0; i < BTREE_MAX_CHILDREN; ++i)
+      self.(btree_child[i]) = world;
+
 Note that this works:
-<pre>
-var .entity indexfield;
-indexfield = btree_child[i];
-self.indexfield = world;
-</pre>
+
+    var .entity indexfield;
+    indexfield = btree_child[i];
+    self.indexfield = world;
+
 The latter one is a global array of (assignable) entity field variables, and looks very similar:
-<pre>
-myfloatfields[2] = health;
-self.(myfloatfields[2]) = 0;
-// equivalent to self.health = 0;
-</pre>
-Do not use arrays when you do not need to - using both arrays and function calls in the same expression can get messed up (**COMPILER BUG**), and arrays are slowly emulated using functions _ArrayGet*myfloatfields_ and _ArraySet*myfloatfields_ the compiler generates that internally do a binary search for the array index.
 
-h1. Peculiar language constructs
+    myfloatfields[2] = health;
+    self.(myfloatfields[2]) = 0;
+    // equivalent to self.health = 0;
+
+Do not use arrays when you do not need to - using both arrays and function calls in the same expression can get messed up (**COMPILER BUG**), and arrays are slowly emulated using functions *ArrayGet\*myfloatfields* and *ArraySet\*myfloatfields* the compiler generates that internally do a binary search for the array index.
+
+Peculiar language constructs
+============================
 
 This section deals with language constructs in FTEQCC that are not similar to anything in other languages.
 
-h2. if not
+if not
+------
 
-There is a second way to do a negated _if_:
+There is a second way to do a negated *if*:
 
-  if not(expression)
-    ...
+if not(expression)
+ …
 
 It compiles to slightly more efficient code than
 
-  if(!expression)
-    ...
+if(!expression)
+ …
 
 and has the notable difference that
 
-  if not("")
-    ...
-
-will not execute (as _""_ counts as true in an _if_ expression), but
+if not(“”)
+ …
 
-  if(!"")
-    ...
+will not execute (as *“”* counts as true in an *if* expression), but
 
-will execute (as both _""_ and _string_null_ is false when boolean operators are used on it).
+if(!“”)
+ …
 
+will execute (as both *“”* and *string\_null* is false when boolean operators are used on it).
 
-h1. Common patterns
+Common patterns
+===============
 
 Some patterns in code that are often encountered in Xonotic are listed here, in no particular order.
 
-h2. Classes in Quake
+Classes in Quake
+----------------
 
-The usual way to handle classes in Quake is using _fields_, function pointers and the special property _classname_.
+The usual way to handle classes in Quake is using *fields*, function pointers and the special property *classname*.
 
-But first, let's look at how the engine creates entities when the map is loaded.
+But first, lets look at how the engine creates entities when the map is loaded.
 
 Assume you have the following declarations in your code:
 
-  entity self;
 .string classname;
 .vector origin;
 .float height;
+entity self;
+ .string classname;
+ .vector origin;
+ .float height;
 
 and the engine encounters the entity
 
-  {
-  "classname" "func_bobbing"
-  "height" "128"
-  "origin" "0 32 -64"
 }
+{
+ “classname” “func\_bobbing”
+ “height” “128”
+ “origin” “0 32 –64”
+ }
 
 then it will, during loading the map, behave as if the following QuakeC code was executed:
 
-  self = spawn();
-  self.classname = "func_bobbing";
-  self.height = 128;
-  self.origin = '0 32 -64';
-  spawnfunc_func_bobbing();
-
+self = spawn();
+ self.classname = “func\_bobbing”;
+ self.height = 128;
+ self.origin = ’0 32 ~~64’;
+ spawnfunc\_func\_bobbing();
 We learn from this:
 * The special global _entity_ variable _self_ is used when "methods" of an object are called, like - in this case - the "constructor" or spawn function _spawnfunc_func_bobbing_.
 * Before calling the spawn function, the engine sets the mapper specified fields to the values. String values can be treated by the QC code as if they are constant strings, that means there is no need to _strzone_ them.
 * Spawn functions always have the _spawnfunc__ name prefix and take no arguments.
 * The _string_ field _classname_ always contains the name of the entity class when it was created by the engine.
 * As the engine uses this pattern when loading maps and this can't be changed, it makes very much sense to follow this pattern for all entities, even for internal use. Especially making sure _classname_ is set to a sensible value is very helpful.
\* The special global *entity* variable *self* is used when “methods” of an object are called, like~~ in this case - the “constructor” or spawn function *spawnfunc\_func\_bobbing*.
\* Before calling the spawn function, the engine sets the mapper specified fields to the values. String values can be treated by the QC code as if they are constant strings, that means there is no need to *strzone* them.
\* Spawn functions always have the *spawnfunc*\_ name prefix and take no arguments.
\* The *string* field *classname* always contains the name of the entity class when it was created by the engine.
\* As the engine uses this pattern when loading maps and this can’t be changed, it makes very much sense to follow this pattern for all entities, even for internal use. Especially making sure *classname* is set to a sensible value is very helpful.
 
 Methods are represented as fields of function type:
 
-  .void() think;
+.void() think;
 
 and are assigned to the function to be called in the spawn function, like:
 
-  void func_bobbing_think()
 {
   // lots of stuff
 }
+void func\_bobbing\_think()
+ {
+ // lots of stuff
+ }
 
-  void spawnfunc_func_bobbing()
 {
-    // ... even more stuff ...
   self.think = func_bobbing_think;
 }
+void spawnfunc\_func\_bobbing()
+ {
+ // … even more stuff …
self.think = func\_bobbing\_think;
+ }
 
 To call a method of the same object, you would use
 
-  self.think();
+self.think();
 
-but to call a method of another object, you first have to set _self_ to that other object, but you typically need to restore _self_ to its previous value when done:
+but to call a method of another object, you first have to set *self* to that other object, but you typically need to restore *self* to its previous value when done:
 
-  entity oldself;
-  // ...
 oldself = self;
 self.think();
 self = oldself;
+entity oldself;
+ // …
+ oldself = self;
+ self.think();
+ self = oldself;
 
-h2. Think functions
+Think functions
+---------------
 
 A very common entry point to QuakeC functions are so-called think functions.
 
 They use the following declarations:
 
-  .void() think;
 .float nextthink;
+.void() think;
+ .float nextthink;
 
-If _nextthink_ is not zero, the object gets an attached timer: as soon as _time_ reaches _nextthink_, the _think_ method is called with _self_ set to the object. Before that, _nextthink_ is set to zero. So a typical use is a periodic timer, like this:
+If *nextthink* is not zero, the object gets an attached timer: as soon as *time* reaches *nextthink*, the *think* method is called with *self* set to the object. Before that, *nextthink* is set to zero. So a typical use is a periodic timer, like this:
 
-  void func_awesome_think()
 {
   bprint("I am awesome!\n");
   self.nextthink = time + 2;
 }
+void func\_awesome\_think()
+ {
bprint(“I am awesome!”);
+ self.nextthink = time + 2;
+ }
 
-  void spawnfunc_func_awesome()
 {
-    // ...
   self.think = func_awesome_think;
   self.nextthink = time + 2;
 }
+void spawnfunc\_func\_awesome()
+ {
+ // …
self.think = func\_awesome\_think;
+ self.nextthink = time + 2;
+ }
 
-h2. Find loops
+Find loops
+----------
 
 One common way to loop through entities is the find loop. It works by calling a built-in function like
 
-  entity find(entity start, .string field, string match) = #18;
+entity find(entity start, .string field, string match) = \#18;
 
 repeatedly. This function is defined as follows:
 
-  * if _start_ is _world_, the first entity _e_ with _e.field==match_ is returned
-  * otherwise, the entity _e_ **after** _start_ in the entity order with _e.field==match_ is returned
 * if no such entity exists, _world_ is returned
+\* if *start* is *world*, the first entity *e* with *e.fieldmatch\_ is returned
+  \* otherwise, the entity \_e\_ \*\*after\*\* \_start\_ in the entity order with \_e.fieldmatch* is returned
\* if no such entity exists, *world* is returned
 
-It can be used to enumerate all entities of a given type, for example _"info_player_deathmatch"_:
+It can be used to enumerate all entities of a given type, for example *“info\_player\_deathmatch”*:
 
-  entity e;
 for(e = world; (e = find(e, classname, "info_player_deathmatch")); )
   print("Spawn point found at ", vtos(e.origin), "\n");
+entity e;
for(e = world; (e = find(e, classname, “info\_player\_deathmatch”)); )
print(“Spawn point found at ”, vtos(e.origin), “”);
 
-There are many other functions that can be used in find loops, for example _findfloat_, _findflags_, _findentity_.
+There are many other functions that can be used in find loops, for example *findfloat*, *findflags*, *findentity*.
 
-Note that the function _findradius_ is misnamed and is not used as part of a find loop, but instead sets up a linked list of the entities found.
+Note that the function *findradius* is misnamed and is not used as part of a find loop, but instead sets up a linked list of the entities found.
 
-h2. Linked lists
+Linked lists
+------------
 
-An alternate way to loop through a set of entities is a linked list. I assume you are already familiar with the concept, so I'll skip information about how to manage them.
+An alternate way to loop through a set of entities is a linked list. I assume you are already familiar with the concept, so Ill skip information about how to manage them.
 
-It is however noteworthy that some built-in functions create such linked lists using the _entity_ field _chain_ as list pointer. Some of these functions are the aforementioned _findradius_, and _findchain_, _findchainfloat_, _findchainflags_ and _findchainentity_.
+It is however noteworthy that some built-in functions create such linked lists using the *entity* field *chain* as list pointer. Some of these functions are the aforementioned *findradius*, and *findchain*, *findchainfloat*, *findchainflags* and *findchainentity*.
 
 A loop like the following could be used with these:
 
-  entity e;
 for(e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
   print("Spawn point found at ", vtos(e.origin), "\n");
+entity e;
for(e = findchain(classname, “info\_player\_deathmatch”); e; e = e.chain)
print(“Spawn point found at ”, vtos(e.origin), “”);
 
-The main advantage of linked lists however is that you can keep them in memory by using other fields than _chain_ for storing their pointers. That way you can avoid having to search all entities over and over again (which is what _find_ does internally) when you commonly need to work with the same type of entities.
+The main advantage of linked lists however is that you can keep them in memory by using other fields than *chain* for storing their pointers. That way you can avoid having to search all entities over and over again (which is what *find* does internally) when you commonly need to work with the same type of entities.
 
-h2. Error handling
+Error handling
+--------------
 
 Error handling is virtually non-existent in QuakeC code. There is no way to throw and handle exceptions.
 
-However, built-in functions like _fopen_ return _-1_ on error.
-
+However, built-in functions like *fopen* return \_~~1\_ on error.
 To report an error condition, the following means are open to you:
-  * Use the _print_ function to spam it to the console. Hopefully someone will read that something went wrong. After that, possibly use _remove_ to delete the entity that caused the error (but make sure there are no leftover references to it!).
-  * Use the _error_ function to abort the program code and report a fatal error with a backtrace showing how it came to it.
-  * Use the _objerror_ function to abort spawning an entity (i.e. removing it again). This also prints an error message, and the entity that caused the error will not exist in game. Do not forget to _return_ from the spawn function directly after calling _objerror_!
-
+ \* Use the *print* function to spam it to the console. Hopefully someone will read that something went wrong. After that, possibly use *remove* to delete the entity that caused the error (but make sure there are no leftover references to it!).
+ \* Use the *error* function to abort the program code and report a fatal error with a backtrace showing how it came to it.
+ \* Use the *objerror* function to abort spawning an entity (i.e. removing it again). This also prints an error message, and the entity that caused the error will not exist in game. Do not forget to *return* from the spawn function directly after calling *objerror*!
 h2. target and targetname
-
-In the map editor, entities can be connected by assigning a name to them in the _target_ field of the targeting entity and the _targetname_ field of the targeted entity.
-
-To QuakeC, these are just strings - to actually use the connection, one would use a find loop:
-
-  entity oldself;
-  oldself = self;
-  for(self = world; (self = find(self, targetname, oldself.target)); )
-    self.use();
-  self = oldself;
-
-
-h2. the enemy field and its friends
-
-As the find loop for _target_ and _targetname_ causes the engine to loop through all entities and compare their _targetname_ field, it may make sense to do this only once when the map is loaded.
-
-For this, a common pattern is using the pre-defined _enemy_ field to store the target of an entity.
-
-However, this can't be done during spawning of the entities yet, as the order in which entities are loaded is defined by the map editor and tends to be random. So instead, one should do that at a later time, for example when the entity is first used, in a think function, or - the preferred way in the Xonotic code base - in an _InitializeEntity_ function:
-
-  void teleport_findtarget()
-  {
-    // ...
-    self.enemy = find(world, targetname, self.target);
-    if(!self.enemy)
-      // some error handling...
-    // ...
-  }
-
-  void spawnfunc_trigger_teleport()
-  {
-    // ...
-    InitializeEntity(self, teleport_findtarget, INITPRIO_FINDTARGET);
-    // ...
-  }
-
-_InitializeEntity_ functions are guaranteed to be executed at the beginning of the next frame, before the _think_ functions are run, and are run in an order according to their priorities (the _INITPRIO__ constants).
-
-h2. if-chains
-
-With default compile options (i.e. if the option _-flo_ is not passed to the compiler), boolean expressions are evaluated fully. This means that in
-
-  if(!flag && SomeComplexFunction(self))
-    ...
-
-_SomeCompexFunction_ is always evaluated, even if _flag_ is true. To avoid this, one can use:
-
-  if(!flag)
-  if(SomeComplexFunction(self))
-    ...
-
+In the map editor, entities can be connected by assigning a name to them in the *target* field of the targeting entity and the *targetname* field of the targeted entity.
+To QuakeC, these are just strings~~ to actually use the connection, one would use a find loop:
+
+entity oldself;
+ oldself = self;
+ for(self = world; (self = find(self, targetname, oldself.target)); )
+ self.use();
+ self = oldself;
+
+the enemy field and its friends
+-------------------------------
+
+As the find loop for *target* and *targetname* causes the engine to loop through all entities and compare their *targetname* field, it may make sense to do this only once when the map is loaded.
+
+For this, a common pattern is using the pre-defined *enemy* field to store the target of an entity.
+
+However, this can’t be done during spawning of the entities yet, as the order in which entities are loaded is defined by the map editor and tends to be random. So instead, one should do that at a later time, for example when the entity is first used, in a think function, or - the preferred way in the Xonotic code base - in an *InitializeEntity* function:
+
+void teleport\_findtarget()
+ {
+ // …
+ self.enemy = find(world, targetname, self.target);
+ if(!self.enemy)
+ // some error handling…
+ // …
+ }
+
+void spawnfunc\_trigger\_teleport()
+ {
+ // …
+ InitializeEntity(self, teleport\_findtarget, INITPRIO\_FINDTARGET);
+ // …
+ }
+
+*InitializeEntity* functions are guaranteed to be executed at the beginning of the next frame, before the *think* functions are run, and are run in an order according to their priorities (the *INITPRIO*\_ constants).
+
+if-chains
+---------
+
+With default compile options (i.e. if the option *~~flo\_ is not passed to the compiler), boolean expressions are evaluated fully. This means that in
+ if(!flag && SomeComplexFunction(self))
+ …
+*SomeCompexFunction* is always evaluated, even if *flag* is true. To avoid this, one can use:
+ if(!flag)
+ if(SomeComplexFunction(self))
+ …
 h2. Tracing
 
-
 h1. Pitfalls and compiler bugs
-
 h2. complex operators
-
-Do not count on the modifying and reading operators like _&#43;=_ or _&#43;&#43;_ to always work. Using them in simple cases like:
-
-  a += 42;
-  for(i = 0; i < n; ++i)
-    ...
-
+Do not count on the modifying and reading operators like *+=* or *++* to always work. Using them in simple cases like:
+ a *= 42;
+ for(i = 0; i \< n;i)
+ …
 is generally safe, but complex constructs like:
-
-  self.enemy.frags += self.value--;
-
+ self.enemy.frags*= self.value—;
 are doomed. Instead, split up such expressions into simpler steps:
-
-  self.enemy.frags = self.enemy.frags + self.value;
-  self.value -= 1;
-
+ self.enemy.frags = self.enemy.frags + self.value;
+ self.value~~= 1;
 The compiler warning **RETURN VALUE ALREADY IN USE** is a clear indicator that an expression was too complex for it to deal with it correctly. If you encounter the warning, do make sure you change the code to no longer cause it, as the generated code **will** be incorrect then.
+Also, do not use the*+=\_ like operators on \_vector\_s, as they are known to create incorrect code and only operate on the *x* component of the vector.
 
-Also, do not use the _+=_ like operators on _vector_s, as they are known to create incorrect code and only operate on the _x_ component of the vector.
-
-h2. functions VS. arrays
+functions VS. arrays
+--------------------
 
 Mixing function calls with array dereferencing, or doing more than one array dereferencing in the same expression, is known to create incorrect code. Avoid constructs like:
 
-  print(ftos(floatarray[i]), " --> ", stringarray[i], anotherstringarray[i], "\n");
-
-as the array dereferencings and the _ftos_ return value are likely to overwrite each other. Instead, simplify it:
-<pre>
+print(ftos(floatarray[i]), " —\> “, stringarray[i], anotherstringarray[i], ”“);
+as the array dereferencings and the *ftos* return value are likely to overwrite each other. Instead, simplify it:
+\<pre\>
 float f;
 string s, s2;
-// ...
+// 
 f = floatarray[i];
 s = stringarray[i];
 s2 = anotherstringarray[i];
-print(ftos(f), " --> ", s, s2, "\n");
-</pre>
-
+print(ftos(f), ” —\> “, s, s2, ”“);
+\</pre\>
 h2. vectoangles does not match makevectors
-
-The pitch angle is inverted between these two functions. You have to negate the pitch (i.e. the _x_ component of the vector representing the euler angles) to make it fit the other function.
-
-As a rule of thumb, _vectoangles_ returns angles as stored in the _angles_ field (used to rotate entities for display), while _makevectors_ expects angles as stored in the _v_angle_ field (used to transmit the direction the player is aiming). There is about just as much good reason in this as there is for 1:1 patch cables. Just deal with it.
-
+The pitch angle is inverted between these two functions. You have to negate the pitch (i.e. the *x* component of the vector representing the euler angles) to make it fit the other function.
+As a rule of thumb, *vectoangles* returns angles as stored in the *angles* field (used to rotate entities for display), while *makevectors* expects angles as stored in the *v\_angle* field (used to transmit the direction the player is aiming). There is about just as much good reason in this as there is for 1:1 patch cables. Just deal with it.
 h1. Entry points
-
 The server-side code calls the following entry points of the QuakeC code:
+ \* **void ClientDisconnect()**: called when a player leaves the server. Do not forget to *strunzone* all *strings* stored in the player entity here, and do not forget to clear all references to the player!
+ \* **void SV\_Shutdown()**: called when the map changes or the server is quit. A good place to store persistent data like the database of race records.
+ \* **void SV\_ChangeTeam(float newteam)**: called when a player changes his team. Can be used to disallow team changes, or to clear the player’s scores.
+ \* **void ClientKill()**: called when the player uses the ”kill" console command to suicide.
+ \* **void RestoreGame()**: called directly after loading a save game. Useful to, for example, load the databases from disk again.
+ \* **void ClientConnect()**: called as soon as a client has connected, downloaded everything, and is ready to play. This is the typical place to initialize the player entity.
+ \* **void PutClientInServer()**: called when the client requests to spawn. Typically puts the player somewhere on the map and lets him play.
+ \* **.float SendEntity(entity to, float sendflags)**: called when the engine requires a CSQC networked entity to send itself to a client, referenced by *to*. Should write some data to *MSG\_ENTITY*. *FALSE* can be returned to make the entity not send. See *EXT\_CSQC* for information on this.
+ \* **void URI\_Get\_Callback(…)**:
+ \* **void GameCommand(string command)**: called when the “sv\_cmd” console command is used, which is commonly used to add server console commands to the game. It should somehow handle the command, and print results to the server console.
+ \* **void SV\_OnEntityNoSpawnFunction()**: called when there is no matching spawn function for an entity. Just ignore this…
+ \* **void SV\_OnEntityPreSpawnFunction**: called before even looking for the spawn function, so you can even change its classname in there. If it remove()s the entity, the spawn function will not be looked for.
+ \* **void SV\_OnEntityPostSpawnFunction**: called ONLY after its spawn function or SV\_OnEntityNoSpawnFunction was called, and skipped if the entity got removed by either.
+ \* **void SetNewParms()**:
+ \* **void SetChangeParms()**:
+ \* **.float customizeentityforclient()**: called for an entity before it is going to be sent to the player specified by *other*. Useful to change properties of the entity right before sending, e.g. to make an entity appear only to some players, or to make it have a different appearance to different players.
+ \* **.void touch()**: called when two entities touch; the other entity can be found in *other*. It is, of course, called two times (the second time with *self* and *other* reversed).
+ \* **.void contentstransition()**:
+ \* **.void think()**: described above, basically a timer function.
+ \* **.void blocked()**: called when a *MOVETYPE\_PUSH* entity is blocked by another entity. Typically does either nothing, reverse the direction of the door moving, or kills the player who dares to step in the way of the Mighty Crusher Door.
+ \* **.void movetypesteplandevent()**: called when a player hits the floor.
+ \* **.void PlayerPreThink()**: called before a player runs his physics. As a special exception, *frametime* is set to 0 if this is called for a client-side prediction frame, as it still will get called for server frames.
+ \* **.void PlayerPreThink()**: called after a player runs his physics. As a special exception, *frametime* is set to 0 if this is called for a client-side prediction frame, as it still will get called for server frames.
+ \* **void StartFrame()**: called at the beginning of each server frame, before anything else is done.
+ \* **void EndFrame()**: called at the end of each server frame, just before waiting until the next frame is due.
+ \* **void SV\_PlayerPhysics()**: allows to replace the player physics with your own code. The movement the player requests can be found in the *vector* field *movement*, and the currently pressed buttons are found in various fields, whose names are aliased to the *BUTTON*\_ macros.
+ \* **void SV\_ParseClientCommand(string command)**: handles commands sent by the client to the server using “cmd …”. Unhandled commands can be passed to the built-in function *clientcommand* to execute the normal engine behaviour.
 
-  * *void ClientDisconnect()*: called when a player leaves the server. Do not forget to _strunzone_ all _strings_ stored in the player entity here, and do not forget to clear all references to the player!
-  * *void SV_Shutdown()*: called when the map changes or the server is quit. A good place to store persistent data like the database of race records.
-  * *void SV_ChangeTeam(float newteam)*: called when a player changes his team. Can be used to disallow team changes, or to clear the player's scores.
-  * *void ClientKill()*: called when the player uses the "kill" console command to suicide.
-  * *void RestoreGame()*: called directly after loading a save game. Useful to, for example, load the databases from disk again.
-  * *void ClientConnect()*: called as soon as a client has connected, downloaded everything, and is ready to play. This is the typical place to initialize the player entity.
-  * *void PutClientInServer()*: called when the client requests to spawn. Typically puts the player somewhere on the map and lets him play.
-  * *.float SendEntity(entity to, float sendflags)*: called when the engine requires a CSQC networked entity to send itself to a client, referenced by _to_. Should write some data to _MSG_ENTITY_. _FALSE_ can be returned to make the entity not send. See _EXT_CSQC_ for information on this.
-  * *void URI_Get_Callback(...)*:
-  * *void GameCommand(string command)*: called when the "sv_cmd" console command is used, which is commonly used to add server console commands to the game. It should somehow handle the command, and print results to the server console.
-  * *void SV_OnEntityNoSpawnFunction()*: called when there is no matching spawn function for an entity. Just ignore this...
-  * *void SV_OnEntityPreSpawnFunction*: called before even looking for the spawn function, so you can even change its classname in there. If it remove()s the entity, the spawn function will not be looked for.
-  * *void SV_OnEntityPostSpawnFunction*: called ONLY after its spawn function or SV_OnEntityNoSpawnFunction was called, and skipped if the entity got removed by either.
-  * *void SetNewParms()*:
-  * *void SetChangeParms()*: 
-  * *.float customizeentityforclient()*: called for an entity before it is going to be sent to the player specified by _other_. Useful to change properties of the entity right before sending, e.g. to make an entity appear only to some players, or to make it have a different appearance to different players.
-  * *.void touch()*: called when two entities touch; the other entity can be found in _other_. It is, of course, called two times (the second time with _self_ and _other_ reversed).
-  * *.void contentstransition()*:
-  * *.void think()*: described above, basically a timer function.
-  * *.void blocked()*: called when a _MOVETYPE_PUSH_ entity is blocked by another entity. Typically does either nothing, reverse the direction of the door moving, or kills the player who dares to step in the way of the Mighty Crusher Door.
-  * *.void movetypesteplandevent()*: called when a player hits the floor.
-  * *.void PlayerPreThink()*: called before a player runs his physics. As a special exception, _frametime_ is set to 0 if this is called for a client-side prediction frame, as it still will get called for server frames.
-  * *.void PlayerPreThink()*: called after a player runs his physics. As a special exception, _frametime_ is set to 0 if this is called for a client-side prediction frame, as it still will get called for server frames.
-  * *void StartFrame()*: called at the beginning of each server frame, before anything else is done.
-  * *void EndFrame()*: called at the end of each server frame, just before waiting until the next frame is due.
-  * *void SV_PlayerPhysics()*: allows to replace the player physics with your own code. The movement the player requests can be found in the _vector_ field _movement_, and the currently pressed buttons are found in various fields, whose names are aliased to the _BUTTON__ macros.
-  * *void SV_ParseClientCommand(string command)*: handles commands sent by the client to the server using "cmd ...". Unhandled commands can be passed to the built-in function _clientcommand_ to execute the normal engine behaviour.