#LyX 1.1 created this file. For more info see http://www.lyx.org/ \lyxformat 218 \textclass scrbook \language american \inputencoding latin1 \fontscheme pslatex \graphics default \paperfontsize 12 \spacing single \papersize Default \paperpackage a4 \use_geometry 1 \use_amsmath 0 \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation skip \defskip medskip \quotes_language english \quotes_times 2 \papercolumns 1 \papersides 2 \paperpagestyle headings \layout Title The Ruamoko Programming Language \layout Author Bill Currie \begin_inset Formula \( \bullet \) \end_inset Jeff Teunissen \layout Publishers QuakeForge Press \newline ;-) \layout Uppertitleback This manual is free; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. \newline \newline This manual is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. \newline \newline You should have received a copy of the GNU General Public License along with this manual: if not, write to: \newline \newline Free Software Foundation, Inc. \newline 59 Temple Place - Suite 330 \newline Boston MA 02111-1307 \newline USA \layout Lowertitleback Copyright © 2002 Bill Currie and Jeff Teunissen \layout Standard \begin_inset LatexCommand \tableofcontents{} \end_inset \layout Addchap Preface \layout Standard In December 1996, Id Software released \emph on Quake \emph default to the world. It's doubtful that they knew at the time that it would spark a revolution -- but such a revolution happened. To the game industry's surprise, people were getting the game not just to play it, but to \emph on change \emph default it\SpecialChar \@. For the first time, people could make whole new games based on the Quake engine without having to rewrite the whole game -- and in fact you couldn't rewrite the whole game, because the main source code wasn't available to the general public. What \series bold was \series default available was something new -- the game wasn't just a game, it was a virtual machine that had a byte-code instruction set -- and it had a compiler that you could use to make new games to run inside that engine. The language (called \emph on QuakeC \emph default ) was kind of crude, and the compiler was even more crude -- but it was a revolutionary development. \layout Standard Now, let's fast-forward to another December -- this time, December 1999. In another revolutionary move, Id Software released the source code to the complete Quake engine. This gave many people the opportunity to do a lot more than just make \begin_inset Quotes eld \end_inset mods \begin_inset Quotes erd \end_inset for Quake. Instead, people could make all-new games without using Quake itself. Many projects started up around this source code, with many aims\SpecialChar \ldots{} but one project grew to be the most dominant: That project is \emph on QuakeForge \emph default . \layout Standard QuakeForge has developed a number of interesting things involving the Quake engine, but most of them are beyond the scope of this manual. This manual documents the \emph on Ruamoko \begin_float footnote \layout Standard The name Ruamoko comes from the Maori name for their god of volcanoes and earthquakes. According to myth, Ruamoko is not yet born, and when he shakes inside the Earth-mother, the world shakes. \end_float language, a language based on Id Software's QuakeC, but which has been expanded in ways far beyond the original language. \layout Standard The idea behind this book is to give new programmers a solid foundation in both of the programming models (procedural and object-oriented) supported by the Ruamoko language, while giving experienced Ruamoko programmers a complete reference for development of game code. \layout Chapter A Tutorial Introduction \layout Standard Let us begin with a quick introduction to Ruamoko. Our aim here is to show the basic elements of the language in real programs, but without getting bogged down in details or rules. At this point, we're not even trying to be complete, or even precise (except that the examples are meant to be correct). We want to get you as quickly as possible to the point where you can write useful programs, and to do that we have to concentrate on the basics: variables and constants, arithmetic, flow control, functions, and the rudiments of input and output. We are intentionally leaving out of this chapter features of Ruamoko that are important for writing bigger programs, or programs to run in an actual Quake engine. These include entities, structures, pointers, most of the operators, objects, and the standard builtin library. \layout Standard This approach has its drawbacks. Most notable is that the complete story on any particular language feature is not found here, and the brief tutorial, just by being brief, may be misleading. And because the examples don't use the full power of Ruamoko, they may not be as elegant or concise as they could be; we \series bold have \series default tried to minimize these effects, but be warned. Another drawback is that later chapters will repeat some of what's presented here. We hope that the repetition will help more than it annoys. \layout Standard In any case, experienced programmers should be able to get an idea, from this chapter, of some of the things that can be done in Ruamoko, for their own needs. Beginners should supplement it by writing small, similar programs of their own. Both groups can use it as a framework on which to hang the more detailed descriptions that begin in later chapters. \layout Section Getting Started \layout Standard The best way to learn a new programming language is by writing programs in it. The first program one writes is almost always the same for all new languages: print the phrase \begin_inset Quotes eld \end_inset Hello, world! \begin_inset Quotes erd \end_inset on the screen. \layout Standard This is the big hurdle. To get past it, you have to be able to create the program text somewhere, compile it, load it successfully, load it, run it, and find out where the output went. With these mechanical details mastered, everything else is relatively easy. \layout Standard In Ruamoko, the program to print \begin_inset Quotes eld \end_inset Hello, world! \begin_inset Quotes erd \end_inset is: \layout LyX-Code #include \newline #include \newline #include \newline \newline void () main = \newline { \newline printf ("Hello, world! \backslash n"); \newline }; \layout Standard To run this program, you first have to compile it. To compile it, you need to save the source code into a file (for example, \family typewriter hello.r \family default ), and create a \family typewriter progs.src \family default file to tell the compiler how to compile it. Here is an example \family typewriter progs.src \family default file: \layout LyX-Code qwaq.dat \newline hello.r \layout Standard The first line of \family typewriter progs.src \family default tells the compiler the name of the compiled object file that it is supposed to save to disk after compilation. Following lines tell it the names of files that are to be used to compile that object file. To compile the source, issue the command \layout LyX-Code qfcc \layout Standard If you haven't screwed anything up, such as omitting a character or misspelling something, the compilation will proceed silently. You should be rewarded with something that looks something like the following: \layout LyX-Code 208 strofs \newline 4 statements \newline 14 functions \newline 30 globaldefs \newline 0 locals size ((null)) \newline 8 fielddefs \newline 52 pr_globals \newline 6 entityfields \newline 1316 TOTAL SIZE \newline Compilation time: 0.0365 seconds. \layout Standard You run \family typewriter qwaq.dat \family default by issuing the command \layout LyX-Code qwaq \layout Standard the program should print \layout LyX-Code Hello, world! \layout Standard to your screen. \layout Standard Now, for some explanations regarding the program itself. All Ruamoko programs, regardless of size, consist mainly of \emph on functions \emph default and \emph on variables \emph default . A function contains statements that tell the compiler what computing operations you want to do, and variables store values used during the operation of the program. Ruamoko functions are roughly equivalent to C's functions, or Pascal's procedures and functions. Our example is a function called \family typewriter main \family default . You can create functions with just about any name you like, but \begin_inset Quotes eld \end_inset \family typewriter main \family default \begin_inset Quotes erd \end_inset is special -- program execution begins there \begin_float footnote \layout Standard This is not precisely true. When used in a game engine, there are certain other functions that are called by the engine during the course of a game. \end_float . This means that every program must have a \family typewriter main \family default function somewhere. \layout Standard Main will usually call other functions to do its job -- some of them you write, and some of them are provided by the virtual machine your program runs inside. The first lines of the program, \layout LyX-Code #include \newline #include \newline #include \layout Standard tell the compiler to include information about the standard variables, constants , \emph on fields \emph default , and \emph on builtins \emph default (also known as \emph on engine functions \emph default ) provided by the environment \begin_float footnote \layout Standard The environment will be described later. \end_float . \layout Standard One way of communicating data between functions is for the calling function to provide a list of values, called arguments, to the function it calls. The parentheses after the function's name surround the argument list. In this example, main is defined to be a function that expects no arguments, which is indicated by an empty list:\SpecialChar ~ \family typewriter () \family default . \layout Standard The statements of a function are enclosed in curly braces,\SpecialChar ~ \family typewriter {} \family default . The function \family typewriter main \family default contains only one statement, \layout LyX-Code printf ("Hello, world! \backslash n"); \layout Standard A function is called by giving its name, followed by a list of arguments enclosed by parentheses, so this calls the function \family typewriter printf \family default with the argument \family typewriter "Hello, world! \backslash n" \family default . \family typewriter printf \family default is a builtin function that prints output, in this case the string of characters between the quotes. \layout Standard A sequence of characters between double quotes, like \family typewriter "Hello, world! \backslash n" \family default , is called a \emph on string constant \emph default or simply a \emph on string \emph default . For the moment, our only use of strings will be as arguments for \family typewriter printf \family default and other functions. \layout Standard The sequence \family typewriter \backslash n \family default in the string is Ruamoko notation for the \emph on newline character \emph default , which when printed tells the terminal (or a game client) to advance to the next line in the output. If you leave out the \family typewriter \backslash n \family default , you will find that there is no advance after the character string is printed. You must use \family typewriter \backslash n \family default to include a newline character in the printf argument; if you try something like \layout LyX-Code printf ("Hello, world! \newline "); \layout Standard the Ruamoko compiler will give you an error message. \layout Standard \family typewriter printf \family default never supplies a newline automatically, so several calls may be used to build up an output line in stages. Our first program could just as easily been written as \layout LyX-Code #include \newline #include \newline #include \newline \newline void () main = \newline { \newline printf ("Hello, "); \newline printf ("world!"); \newline printf (" \backslash n"); \newline }; \layout Standard and it would have produced identical output. \layout Standard Note that \backslash n represents only a single character. An escape character like \backslash n gives you a general way to express hard-to-type or invisible characters. Among the others are \backslash t for a tab, \backslash b for a backspace, \backslash " for a double-quote, and \backslash \backslash for the backslash character itself. There is a complete list in [section] \layout Section Variables and Mathematical Expressions \layout Chapter Language Reference \layout Standard This is currently just new stuff in \family typewriter \series bold qfcc \family default \series default . \layout Section New Type Features \layout Subsection New Types \layout List \labelwidthstring 00.00.0000 \family typewriter integer \family default 32 bit signed integer \layout List \labelwidthstring 00.00.0000 \family typewriter id \family default generic object pointer \layout List \labelwidthstring 00.00.0000 \family typewriter Class \family default class object pointer \layout List \labelwidthstring 00.00.0000 \family typewriter Protocol \family default protocol object pointer \layout List \labelwidthstring 00.00.0000 \family typewriter Method \family default method pointer \layout List \labelwidthstring 00.00.0000 \family typewriter SEL \family default selector \layout List \labelwidthstring 00.00.0000 \family typewriter IMP \family default message implementation \layout Standard \family typewriter id \family default , \family typewriter Class \family default , \family typewriter Protocol \family default , \family typewriter Method \family default , \family typewriter SEL \family default and \family typewriter IMP \family default are part of \family typewriter \series bold qfcc \family default \series default 's Objective-QC extensions. \layout Subsection Enumerators \layout Standard as per C \layout Subsection Structures \layout LyX-Code struct foo { \newline integer bar; \newline float baz; \newline void () func; \newline }; \layout Standard Structures with no elements can be declared for making opaque types (particularl y useful for engine interface functions). \layout Subsection Arrays \layout LyX-Code integer [13] array; \layout Subsection Pointers \layout Standard Pointers are declared the same way as arrays, but with no number in the \family typewriter [] \family default s. In fact, arrays are just pointers with limited (compile-time) bounds checking (constant indices). \layout Subsection Complex types \layout Standard Complex types can be created by nesting type declarations within \family typewriter () \family default s. e.g.: \layout LyX-Code (.float) (string name) find_field; \layout Standard declares a function ( \family typewriter find_field \family default ) taking a string parameter and returning a float field `offset'. Without the \family typewriter () \family default s around the \family typewriter .float \family default , the declaration would be a function field. \layout Subsection \family typewriter typedef \layout Standard By using \family typewriter typedef \family default complex types can be given symbolic names. e.g.: \layout LyX-Code struct foo_s {}; \newline typedef foo_s [] foo_t; \layout Standard creates type \family typewriter foo_t \family default which is a pointer to the structure \family typewriter foo_s \family default (which happens to be opaque). \layout Subsection Variable-argument functions \layout Standard Typed parameters preceding the ellipsis are allowed, e.g.: \family typewriter void (string fmt, ...) printf; \layout Standard More importantly, it is now possible to write vararg functions in QC. \family typewriter @argc \family default gives the number of parameters passed through the ellipsis and \family typewriter @argv \family default is an array of vectors representing the parameters passed through \family typewriter ... \family default . \layout Standard \series bold \emph on Warning: attempting to pass \family typewriter @argv \family default to a non-engine function will not work. This is because of changes in how local variables are handled by the compiler. \layout Subsection Improved type checking \layout Standard Function parameters and return types are are fully checked, including the number of parameters passed to a function. Functions with different return types and/or different parameter types or counts are distinct types and mixing them up will cause a type mismatch error. Similar for pointers to various types. \layout Section Variables \layout Subsection Local variables \layout Subsubsection Initialization \layout Standard Local variables of basic types can now be initialized when declared. e,g, \layout Verse \family typewriter local integer elite = 31337; \layout Subsubsection Unused variables \layout Standard Local variables that are declared but not used produce a warning. \layout Subsubsection Uninitialized variables \layout Standard Checks are done to ensure that local variables have been initialized before being used. However, these checks are not perfect and false positives are very likely in complex code. Occurrences of false negatives are not known, but the possibility of their existence remains and any examples of false negatives should be reported as bugs. \layout Subsection Complex global variables \layout Standard Global array variables can be initialized using \family typewriter = { \emph on element-list \emph default }; \family default . Element lists may be nested using \family typewriter {} \family default . Structures cannot currently be initialized, but this is a FIXME :) \layout Subsection Magic variables \layout List \labelwidthstring 00.00.0000 \family typewriter @self \family default Automagically declared entity variable the engine will use for \family typewriter touch \family default and \family typewriter think \family default functions. This allows \family typewriter self \family default to be used as the object hidden parameter in methods. \layout List \labelwidthstring 00.00.0000 \family typewriter @this \family default Automagically declared \family typewriter id \family default field that the engine expects to point to the object associated with the entity. The engine will use this field, if it exists, to set the \family typewriter self \family default parameter to \family typewriter touch \family default and \family typewriter think \family default methods (the engine assumes it's calling a method rather than a function if the @this field is used. \layout List \labelwidthstring 00.00.0000 \family typewriter @argc \family default Number of parameters passed through \family typewriter ... \family default in vararg functions. Not valid elsewhere. \layout List \labelwidthstring 00.00.0000 \family typewriter @argv \family default Array of vectors representing the parameters passed through \family typewriter ... \family default in vararg functions. Not valid elsewhere. \layout Section Code constructs \layout Subsection \family typewriter break \layout Standard The \family typewriter break \family default statement can be used to leave a loop ( \family typewriter while \family default , \family typewriter do \family default ... \family typewriter while \family default , or \family typewriter for \family default ) prematurely. The \family typewriter break \family default statement is also used to leave a \family typewriter switch \family default statement. \layout Subsection \family typewriter continue \layout Standard The \family typewriter continue \family default statement is used to jump to the beginning of a loop. In \family typewriter for \family default loops, the test and post expressions are evaluated before continuing with the loop. \layout Subsection \family typewriter for \layout Standard The \family typewriter for \family default loop is: \layout LyX-Code for ( \emph on initialization-expression \emph default ; \emph on test-expression \emph default ; \emph on post-expression \emph default ) \layout LyX-Code \emph on statement \layout Standard and is equivalent to \layout LyX-Code \emph on initialization expression \layout LyX-Code while ( \emph on test expression \emph default ) { \layout LyX-Code \emph on statement \layout LyX-Code \emph on post expression \layout LyX-Code } \layout Subsection \family typewriter switch \layout Standard The \family typewriter switch \family default statement is used to select between multiple code blocks based on the value of an expression. \layout LyX-Code switch ( \emph on test expression \emph default ) { \newline case \emph on value \emph default : \newline \emph on optional statements \newline \emph default case \emph on value \emph default : \newline \emph on optional statements \emph default \newline default: \newline \emph on optional statements \emph default \newline } \layout Standard Code execution starts at the selected \family typewriter case \family default and continues on to the end of the switch block. Following \family typewriter case \family default s do \emph on not \emph default affect code execution. If this behavior is not desired, as is usual, then a \family typewriter break \family default statement is required to cause the code to jump to the end of the \family typewriter switch \family default , skipping any intervening code. That is, just like C. \layout Subsubsection \family typewriter \emph on test expression \layout Standard The test expression may result in a float, string or integer value. \layout Subsubsection \family typewriter case \emph on value \layout Verse \family typewriter case \emph on value \emph default : \layout Standard The case value may be of any constant type consistent with the test expression of the \family typewriter switch \family default . \layout Subsubsection \family typewriter default \layout Standard If specified, this is where execution will go when no \family typewriter case \family default has been selected by the test expression. If not specified, and no \family typewriter case \family default has been selected by the test expression, the \family typewriter switch \family default does not execute any code within the block. \layout Section Expressions \layout Subsection Binary \layout List \labelwidthstring 00.00.0000 \family typewriter <<\SpecialChar ~ >> \family default bit shift left and right \layout List \labelwidthstring 00.00.0000 \family typewriter ^ \family default bitwise exclusive or \layout List \labelwidthstring 00.00.0000 \family typewriter % \family default modulus \layout Subsubsection Assignment \layout List \labelwidthstring 00.00.0000 \family typewriter \emph on op \emph default = \family default equivalent to \family typewriter a = a \emph on op \emph default b \family default . \layout Subsection Unary \layout List \labelwidthstring 00.00.0000 \family typewriter ~ \family default bitwise not \layout List \labelwidthstring 00.00.0000 \family typewriter & \family default address \layout List \labelwidthstring 00.00.0000 \family typewriter ++ \emph on e \emph default \SpecialChar ~ -- \emph on e \family default \emph default pre-increment and decrement \layout List \labelwidthstring 00.00.0000 \family typewriter \emph on e \emph default ++\SpecialChar ~ \emph on e \emph default -- \family default post-increment and decrement \layout Subsection Other \layout List \labelwidthstring 00.00.0000 \family typewriter \emph on type\SpecialChar ~ \emph default ( \emph on expr \emph default ) \family default cast expression. Only works for converting between integer and float types and between pointer types. \layout List \labelwidthstring 00.00.0000 \family typewriter \emph on expr \emph default [ \emph on expr \emph default ] \family default array indexing. \layout List \labelwidthstring 00.00.0000 \family typewriter \emph on expr \emph default ? \emph on expr \emph default : \emph on expr \family default \emph default C's trinary expression \layout List \labelwidthstring 00.00.0000 \family typewriter [ \emph on expr \emph default \SpecialChar ~ \emph on exprs \emph default ] \family default Objective-QC message \layout List \labelwidthstring 00.00.0000 \family typewriter @selector( \emph on exprs \emph default ) \family default Objective-QC selector expression \layout List \labelwidthstring 00.00.0000 \family typewriter @protocol( \emph on name \emph default ) \family default Objective-QC protocol expression \layout List \labelwidthstring 00.00.0000 \family typewriter @encode( \emph on type \emph default ) \family default Objective-QC type encoding expression \layout List \labelwidthstring 00.00.0000 \family typewriter @ \emph on string \family default \emph default Objective-QC string object. Currently identical to a normal QC string. \the_end