]> git.xonotic.org Git - xonotic/xonotic.wiki.git/blob - Introduction-to-QuakeC.md
Upload attachment items.jpg
[xonotic/xonotic.wiki.git] / Introduction-to-QuakeC.md
1 QuakeC
2 ======
3
4 About QuakeC
5 ------------
6
7 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 GMQCC dialect of QuakeC, so only this dialect will be described (as well as some common extensions among Quake engines).
8
9 There are several documents describing the original version of QC as used in Quake 1:
10 - an [old version](http://www.gamers.org/dEngine/quake/spec/quake-spec34/index1.htm) which is a part of unofficial [Quake Documentation](http://www.gamers.org/dEngine/quake/spec/quake-spec34/)
11 - a probably slightly [newer version](http://www.cataboligne.org/extra/qcmanual.html)
12 - a [newer and extended version](http://pages.cs.wisc.edu/~jeremyp/quake/quakec/quakec.pdf) in PDF
13
14 Even this page is outdated and incomplete, not all GMQCC QuakeC constructs are described here and some of the bugs mentioned here have already been fixed.
15
16 Other resources
17 ---------------
18
19 - [QC Tutorial for Absolute Beginners](https://web.archive.org/web/20091118154016/http://forums.inside3d.com/viewtopic.php?t=1286)
20 - [List of builtins on quakewiki.org](https://quakewiki.org/wiki/List_of_builtin_functions)
21 - comments and `doc.md` in the `qcsrc/dpdefs` directory
22
23 Example code
24 ------------
25
26 To see what QuakeC looks like, here is a piece of example code:
27
28 ```c
29 // needed declarations:
30 float vlen(vector v) = #12;
31 entity nextent(entity e) = #47;
32 .string classname;
33 .vector origin;
34 // ...
35 entity findchain(.string fld, string match)
36 {
37     entity first, prev;
38     first = prev = world;
39     for(entity e = world; (e = nextent(e)); e++) {
40         if (e.fld == match) {
41             e.chain = world;
42             if (prev) {
43                 prev.chain = e;
44             } else {
45                 first = e;
46             }
47             prev = e;
48         }
49     }
50     return first;
51 }
52 // ...
53 entity findnearestspawn(vector v)
54 {
55     entity nearest;
56     for (entity e = findchain(classname, "info_player_deathmatch"); e; e = e.chain) {
57         if (!nearest) {
58             nearest = e;
59         } else if(vlen(e.origin - v) < vlen(nearest.origin - v)) {
60             nearest = e;
61         }
62     }
63     return nearest;
64 }
65 ```
66
67 **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
68
69 Variables
70 =========
71
72 Declaring
73 ---------
74
75 To declare a variable, the syntax is the same as in C:
76
77 ```c
78 float i;
79 ```
80
81 Whenever a variable declaration could be interpreted as something else by the compiler, the *var* keyword helps disambiguating. For example,
82
83 ```c
84 float(float a, float b) myfunc;
85 ```
86
87 is an old-style function declaration, while
88
89 ```c
90 var float(float a, float b) myfunc;
91 ```
92
93 declares a variable of function type. An alternate and often more readable way to disambiguate variable declarations is using a *typedef*, like so:
94
95 ```c
96 typedef float(float, float) myfunc_t;
97 myfunc_t myfunc;
98 ```
99
100 Scope
101 -----
102
103 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%.
104 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.
105
106 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.
107
108 Types
109 =====
110
111 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`. GMQCC also adds `arrays`, although these are slow. Note that there are no pointers!
112
113 There are also `int` and `bool` typedefs, but no guarantees are made on the range of values as they are currently not supported by GMQCC.
114
115 float
116 -----
117
118 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.
119
120 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.
121
122 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`.
123
124 vector
125 ------
126
127 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. GMQCC also accepts dot notation to access these components: `v.x`, `v.y` and `v.z`
128
129 **COMPILER BUG:** Always use `entity.vector_x = float` instead of `entity.vector.x = float`, as the latter creates incorrect code! Reading from vectors is fine, however.
130
131 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. Multiplying two vectors yields their dot product of type float.
132
133 Common functions to be used on vectors are `vlen` (vector length), `normalize` (vector divided by its length, i.e. a unit vector).
134
135 Vector literals are written like `'1 0 0'`.
136
137 string
138 ------
139
140 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:
141 -  **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*.
142
143 -   **strcat** concatenates 2 to 8 strings together, as in:
144     ```c
145     strcat("a", "b", "c") == "abc";
146     ```
147
148 -   **strstrofs(haystack, needle, offset)** searches for an occurrence of one string in another, as in:
149     ```c
150     strstrofs("haystack", "ac", 0) == 5;
151     ```
152
153 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.
154
155 -   **strreplace(old, new, string)** searches for certain characters in a string and replaces them with other characters, as in:
156     ```c
157     strreplace("de", "con", "destruction") == "construction";
158     ```
159
160 -   **substring(string, startpos, length)** returns part of a string.
161
162 The offset is *0*-based here, too. A length of `-1` designates the end of the string (it will return the part of the string after the start position), a length of `-2` designates the penultimate character of the string, and so on.
163
164 -   **strtoupper(string)** capitalizes a string.
165 -   **strtolower(string)** lowercases a string.
166
167 Note that there are different kinds of *strings*, regarding memory management:
168
169 -   **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.
170 -   **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:
171     +   To allocate a string, do for example:
172         ```c
173         myglobal = strzone(strcat("hello ", "world"));
174         ```
175
176     +   To free the string when it is no longer needed, do:
177         ```c
178         strunzone(myglobal);
179         ```
180
181 -   **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.
182 -   **Constant strings:** A string literal like *“foo”* gets permanent storage assigned by the compiler. There is no need to *strzone* such strings.
183 -   **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:
184     +   Assigning to a global string variable:
185         ```c
186         if (myglobal) {
187             strunzone(myglobal);
188         }
189
190         myglobal = strzone(...);
191         ```
192
193     +   Freeing the global string variable:
194         ```c
195         if (myglobal) {
196             strunzone(myglobal);
197         }
198
199         myglobal = string_null;
200         ```
201
202     +   Checking if a global string value has been set:
203         ```c
204         if (myglobal) {
205             value has been set;
206         } else {
207             string has not yet been set;
208         }
209         ```
210
211 entity
212 ------
213
214 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:
215
216 ```c
217 .float myfield;
218 ```
219
220 and then all objects *e* get a field that can be accessed like in *e.myfield*.
221
222 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).
223
224 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*).
225
226 fields
227 ------
228
229 A reference to such a field can be stored too, in a field variable. It is declared and used like
230
231 ```c
232 .float myfield;
233 // ...
234 // and in some function:
235 var .float myfieldvar;
236 myfieldvar = myfield;
237 e.myfieldvar = 42;
238 ```
239
240 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.
241
242 functions
243 ---------
244
245 Functions work just like in C:
246
247 ```c
248 float sum3(float a, float b, float c)
249 {
250     return a + b + c;
251 }
252 ```
253
254 However, the syntax to declare function pointers is simplified:
255
256 ```c
257 // in global scope
258 typedef float(float, float, float) op3func_t;
259 var float(float a, float b, float c) f;
260 op3func_t g;
261
262 // in local scope
263 f = sum3;
264 g = f;
265 print(ftos(g(1, 2, 3)), "\n"); // prints 6
266 ```
267
268 Also note that the *var* keyword is used again to disambiguate from a global function declaration.
269
270 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):
271
272 ```c
273 float(float a, float b) sum2 = {
274     return a + b;
275 }
276 ```
277
278 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:
279
280 ```c
281 string strcat(string a, string b, ...) = #115;
282 ```
283
284 The function/field syntax is ambiguous. In global scope a declaration can be a variable, field or function. In local scope, it's always a variable. The `var` keyword can be used in global scope to treat it as local scope (always declaring a variable). The following table shows declarations in global scope:
285
286 | Example code | Meaning |
287 |--------------|---------|
288 | `.float a;` | Entity field of type `float` |
289 | `float(float x1) a;` or `float a(float x1);` | Function with a `float` param returning `float` |
290 | `.float a(float x1);` | Function with a float param returning a `float` field reference |
291 | `.float(float x1) a;` | Entity field of type function with a `float` param returning `float` |
292 | `.float(float x1) a(float x2);` | Function with a `float` param returning a field reference of type function with a `float` param returning `float` |
293
294 These rules were determined by experimenting with GMQCC:
295 - if there are parentheses after the name, it's always a function
296 - else if it starts with a period, it's a field
297 - else if there are parentheses after the type, it's a function (using the old QC syntax)
298 - else it's a variable
299
300 GMQCC allows even weirder declarations like `float f(float)();` which can be called as `f()(42);`. It's not clear whether this behavior is intentional or the result of one of the many compiler bugs.
301
302 void
303 ----
304
305 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.
306
307 arrays
308 ------
309
310 As the QuakeC virtual machine provides no pointers or similar ways to handle arrays, array support is added by GMQCC and very limited. Arrays can only be global, must have a fixed size (not dynamically allocated), and are a bit slow. Almost as great as in FORTRAN, except they can’t be multidimensional either!
311
312 You declare arrays like in C:
313
314 ```c
315 #define MAX_ASSASSINS 16
316 entity assassins[MAX_ASSASSINS];
317 #define BTREE_MAX_CHILDREN 5
318 .entity btree_child[BTREE_MAX_CHILDREN];
319 #define MAX_FLOATFIELDS 3
320 var .float myfloatfields[MAX_FLOATFIELDS];
321 ```
322
323 The former is a global array of entities and can be used the usual way:
324
325 ```c
326 assassins[self.assassin_index] = self;
327 ```
328
329 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:
330
331 ```c
332 for (int i = 0; i < BTREE_MAX_CHILDREN; i++)
333     self.(btree_child[i]) = world;
334 ```
335
336 Note that this works:
337
338 ```c
339 var .entity indexfield;
340 indexfield = btree_child[i];
341 self.indexfield = world;
342 ```
343
344 The latter one is a global array of (assignable) entity field variables, and looks very similar:
345
346 ```c
347 myfloatfields[2] = health;
348 self.(myfloatfields[2]) = 0;
349 // equivalent to self.health = 0;
350 ```
351
352 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.
353
354 Peculiar language constructs
355 ============================
356
357 This section deals with language constructs in QuakeC that are not similar to anything in other languages.
358
359 if not (deprecated)
360 -------------------
361
362 There is a second way to do a negated *if*:
363
364 ```c
365 if not(expression)
366     ...
367 ```
368
369 It compiles to the same code as
370
371 ```c
372 if (!expression)
373     ...
374 ```
375
376 and has the notable difference that
377
378 ```c
379 if not("")
380     ...
381 ```
382
383 will not execute (as *“”* counts as true in an *if* expression), but
384
385 ```c
386 if (!"")
387     ...
388 ```
389
390 will execute (as both `""` and `string_null` is false when boolean operators are used on it).
391
392 Common patterns
393 ===============
394
395 Some patterns in code that are often encountered in Xonotic are listed here, in no particular order.
396
397 Classes in Quake
398 ----------------
399
400 The usual way to handle classes in Quake is using *fields*, function pointers and the special property *classname*.
401
402 But first, let’s look at how the engine creates entities when the map is loaded.
403
404 Assume you have the following declarations in your code:
405
406 ```c
407 entity self;
408     .string classname;
409     .vector origin;
410     .float height;
411 ```
412
413 and the engine encounters the entity
414
415 ```c
416 {
417     "classname" "func_bobbing"
418     "height" "128"
419     "origin" "0 32 –64"
420 }
421 ```
422
423 then it will, during loading the map, behave as if the following QuakeC code was executed:
424
425 ```c
426 self = spawn();
427 self.classname = "func_bobbing";
428 self.height = 128;
429 self.origin = '0 32 -64';
430 spawnfunc_func_bobbing();
431 ```
432
433 We learn from this:
434 -   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`.
435 -   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.
436 -   Spawn functions always have the *spawnfunc\_* name prefix and take no arguments.
437 -   The *string* field *classname* always contains the name of the entity class when it was created by the engine.
438 -   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.
439
440 Methods are represented as fields of function type:
441
442 ```c
443 .void() think;
444 ```
445
446 and are assigned to the function to be called in the spawn function, like:
447
448 ```c
449 void func_bobbing_think()
450 {
451     // lots of stuff
452 }
453 ```
454
455 ```c
456 void spawnfunc_func_bobbing()
457 {
458     // ... even more stuff ...
459     self.think = func_bobbing_think;
460 }
461 ```
462
463 To call a method of the same object, you would use
464
465 ```c
466 self.think();
467 ```
468
469 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:
470
471 ```c
472 entity oldself;
473 // ...
474 oldself = self;
475 self.think();
476 self = oldself;
477 ```
478
479 Think functions
480 ---------------
481
482 A very common entry point to QuakeC functions are so-called think functions.
483
484 They use the following declarations:
485
486 ```c
487 .void() think;
488 .float nextthink;
489 ```
490
491 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:
492
493 ```c
494 void func_awesome_think()
495 {
496     bprint("I am awesome!");
497     self.nextthink = time + 2;
498 }
499 ```
500
501 ```c
502 void spawnfunc_func_awesome()
503 {
504     // ...
505     self.think = func_awesome_think;
506     self.nextthink = time + 2;
507 }
508 ```
509
510 Find loops
511 ----------
512
513 One common way to loop through entities is the find loop. It works by calling a built-in function like
514
515 ```c
516 entity find(entity start, .string field, string match) = #18;
517 ```
518
519 repeatedly. This function is defined as follows:
520
521 -   if *start* is *world*, the first entity *e* with `e.field==match` is returned
522 -   otherwise, the entity *e* **after** *start* in the entity order with `e.field==match` is returned
523 -   if no such entity exists, *world* is returned
524
525 It can be used to enumerate all entities of a given type, for example `"info_player_deathmatch"`:
526
527 ```c
528 for (entity e = world; (e = find(e, classname, "info_player_deathmatch")); )
529     print("Spawn point found at ", vtos(e.origin), "\n");
530 ```
531
532 There are many other functions that can be used in find loops, for example *findfloat*, *findflags*, *findentity*.
533
534 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.
535
536 Linked lists
537 ------------
538
539 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.
540
541 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*.
542
543 A loop like the following could be used with these:
544
545 ```c
546 for (entity e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
547         print("Spawn point found at ", vtos(e.origin), "\n");
548 ```
549
550 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.
551
552 Error handling
553 --------------
554
555 Error handling is virtually non-existent in QuakeC code. There is no way to throw and handle exceptions.
556
557 However, built-in functions like *fopen* return `-1` on error.
558 To report an error condition, the following means are open to you:
559 -   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!).
560 -   Use the *error* function to abort the program code and report a fatal error with a backtrace showing how it came to it.
561 -   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*!
562
563 target and targetname
564 ---------------------
565
566 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.
567 To QuakeC, these are just strings - to actually use the connection, one would use a find loop:
568
569 ```c
570 entity oldself = self;
571 for (self = world; (self = find(self, targetname, oldself.target)); )
572     self.use();
573 self = oldself;
574 ```
575
576 the enemy field and its friends
577 -------------------------------
578
579 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.
580
581 For this, a common pattern is using the pre-defined *enemy* field to store the target of an entity.
582
583 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:
584
585 ```c
586 void teleport_findtarget()
587 {
588     // ...
589     self.enemy = find(world, targetname, self.target);
590     if (!self.enemy)
591         // some error handling...
592     // ...
593 }
594 ```
595
596 ```c
597 void spawnfunc_trigger_teleport()
598 {
599     // ...
600     InitializeEntity(self, teleport_findtarget, INITPRIO_FINDTARGET);
601     // ...
602 }
603 ```
604
605 *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).
606
607 Tracing
608 -------
609
610 Pitfalls and compiler bugs
611 ==========================
612
613 variable shadowing
614 ------------------
615
616 ```c
617 .float height;
618 void update_height(entity e, float height) {
619     e.height = height;
620 }
621 ```
622 `error: invalid types in assignment: cannot assign .float to float`
623
624 The height *field* overrides the height *parameter*; change the parameter name somehow (`_height`).
625
626 complex operators
627 -----------------
628
629 Do not count on the modifying and reading operators like *+=* or *++* to always work. Using them in simple cases like:
630 ```c
631 a += 42;
632 for (int i = 0; i < n; i++) {
633     ...
634 }
635 ```
636 is generally safe, but complex constructs like:
637 ```c
638 self.enemy.frags += self.value--;
639 ```
640 are doomed. Instead, split up such expressions into simpler steps:
641 ```c
642 self.enemy.frags = self.enemy.frags + self.value;
643 self.value -= 1;
644 ```
645 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.
646 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.
647
648 functions VS. arrays
649 --------------------
650
651 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:
652
653 ```c
654 print(ftos(floatarray[i]), " --> ", stringarray[i], anotherstringarray[i], "\n");
655 ```
656
657 as the array dereferencings and the *ftos* return value are likely to overwrite each other. Instead, simplify it:
658 ```c
659 float f;
660 string s, s2;
661 // ...
662 f = floatarray[i];
663 s = stringarray[i];
664 s2 = anotherstringarray[i];
665 print(ftos(f), " --> ", s, s2, "\n");
666 ```
667
668 vectoangles does not match makevectors
669 --------------------------------------
670
671 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.
672 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.
673
674 bound
675 -----
676
677 A bound is a variable that was previously free, but has been bound to a specific value or set of values. If x > upperlimit the upperlimit is returned, if x < lowerlimit then lowerlimit is returned, if lowerlimit < x < upperlimit then x is returned. That function returns an x value calling this way: 
678 ```c
679 bound(lower_limit, x, upper_limit)
680 ```
681
682 Ternary operator
683 ----------------
684
685 QuakeC allows ternary operators like in C:
686 ```c
687 int a = 2;
688 int b = 3;
689 int c = 6;
690 int d = 8;
691 int max = (a > b) ? c : d;
692 ```
693 More [**info**](https://www.geeksforgeeks.org/conditional-or-ternary-operator-in-c-c/).
694
695 There is a complex example using `bound` function with this operator:
696 ```c
697 bound(1, ((hunter_count >= 1) ? hunter_count : floor(total * hunter_count)), total - 1);
698 bool wholenumber = (hunter_count >= 1) //is hunter count a specified whole number or percentage
699
700 if (!wholenumber) //if hunters are defined with percentage count
701 {
702  int z = total * hunter_count //wanted percentage amount from total is z
703  int y = floor(z) //round z downwards to nearest whole number
704 }
705
706 int x = (wholenumber ? hunter_count : y) //if whole number was given use it, 
707 //if not use y which is calculated above
708 bound(1, x, total - 1) //use the value x if it's above 1 but below (total - 1)
709 //Otherwise use the bounding value of that direction to quarantee that 
710 //there is always at least 1 hunter and always at least 1 survivor
711 ```
712
713 Entry points
714 ============
715
716 The server-side code calls the following entry points of the QuakeC code:
717
718 -   **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!
719 <br />
720
721 -   **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.
722 <br />
723
724 -   **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.
725 <br />
726
727 -   **void ClientKill()**: called when the player uses the ”kill" console command to suicide.
728 <br />
729
730 -   **void RestoreGame()**: called directly after loading a save game. Useful to, for example, load the databases from disk again.
731 <br />
732
733 -   **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.
734 <br />
735
736 -   **void PutClientInServer()**: called when the client requests to spawn. Typically puts the player somewhere on the map and lets him play.
737 <br />
738
739 -   **.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.
740 <br />
741
742 -   **void URI\_Get\_Callback(...)**:
743 <br />
744
745 -   **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.
746 <br />
747
748 -   **void SV\_OnEntityNoSpawnFunction()**: called when there is no matching spawn function for an entity. Just ignore this...
749 <br />
750
751 -   **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.
752 <br />
753
754 -   **void SV\_OnEntityPostSpawnFunction**: called ONLY after its spawn function or SV\_OnEntityNoSpawnFunction was called, and skipped if the entity got removed by either.
755 <br />
756
757 -   **void SetNewParms()**:
758 <br />
759
760 -   **void SetChangeParms()**:
761 <br />
762
763 -   **.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.
764 <br />
765
766 -   **.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).
767 <br />
768
769 -   **.void contentstransition()**:
770 <br />
771
772 -   **.void think()**: described above, basically a timer function.
773 <br />
774
775 -   **.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.
776 <br />
777
778 -   **.void movetypesteplandevent()**: called when a player hits the floor.
779 <br />
780
781 -   **.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.
782 <br />
783
784 -   **.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.
785 <br />
786
787 -   **void StartFrame()**: called at the beginning of each server frame, before anything else is done.
788 <br />
789
790 -   **void EndFrame()**: called at the end of each server frame, just before waiting until the next frame is due.
791 <br />
792
793 -   **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.
794 <br />
795
796 -   **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.
797 <br />