• Register
Post tutorial RSS Learning QC For Nexuiz Part 1

This is my first tutorial on learning QC for Nexuiz. QC is the language used for the gamecode, and is pretty easy to learn. Once you have the hang of it it's one of the most powerful modding systems there is.

Posted by on - Basic Server Side Coding



Learning QC For Nexuiz Part 1

Welcome to the first in my hopefully good series of QC tutorials for Nexuiz. My intention in these tutorials is to teach the very basics of QC to absolute beginners. Pay attention at the back! Put down that paper aeroplane Jenkins! We've got some learning to do.


In this lesson, you will discover how to make your very first Nexuiz modification. I'll explain everything as we go along. By the way, if you ever get better than me at QC I'll eat your face.

Firstly, let me give you a quick explaination of what QC is. QC stands for QuakeC, as it was a language originally designed by id software for the game Quake. Since Nexuiz is based on a modified Quake engine, Nexuiz also uses QC.

QC in Nexuiz is written in .C and .H files, which are compiled by a program called QCC2.EXE to a progs.dat. The progs.dat is read by the DarkPlaces engine, and it takes the game code from there.

The QC code doesn't cover everything about Nexuiz. Some code is handled in the DarkPlaces engine itself. What is covered by the QC code includes: The weapons, the player movement and animation, all item code etc. Basically it's all code relating directly to the gameplay. The engine code is more concerned with rendering the game, netcode etc.

Ok, let's get started. The first thing you need to do is to create a new directory for our mod. Go to the Nexuiz directory, and create a new directory inside it, called mymod or something equally rubbish. Next you need to put the Nexuiz QC source code into this directory. Go to the nexuiz/sources directory, and copy the game directory. Paste the directory into your new mymod folder. It should be nexuiz/mymod/game.

Next, open up the file called progs.src from the nexuiz/mymod/game directory with a text editor. This is the file that contains a list of all the .H and .C files to be compiled. At the very top of the file is a line that reads:

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   ../data/progs.dat   </strong></span> </span>

This tells the compiler where to put the compiled progs.dat file. We want it in the nexuiz/mymod directory, so change that line to read:

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   ../progs.dat   </strong></span> </span>

This will of course put it in the correct directory. Now save progs.src and close it. Go to the nexuiz/mymod/game directory and run QCC2.EXE to compile the code. If you are a Linux or Mac user, you will have to get a copy of fteqcc, the source code for which is here. You'll have to ask elsewhere for help on that, I'm a Windows man for my sins. Anyway, once you run the compiler it should load a classy DOS Box and run. It will list all the files in a couple of seconds then stop. Assuming it hasn't reported any errors, close the DOS Box. Go to the nexuiz/mymod directory. It should now contain a compiled progs.dat file. You could run this mod now, but since we've not changed any of the code yet that would be pretty daft. You're not daft, are you?

Ok, so lets get going into the code. But first, what do we want to do? I think for this tutorial I'll start very simple. Let's make a Message Of The Day, a message which appears briefly in the center of the screen when players connect to your server. Got it? Let's do it.

Open the file nexuiz/mymod/game/gamec/cl_client.c. This QC file is comcerned with dealing with things like where players spawn, what to do when the connect and disconnect etc. These are the client functions. QC files are split into functions, which are self-contained sections of code. A very simple function looks like this one from the top of the file:

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   void info_player_start (void)    {    self.classname = &quot;info_player_deathmatch&quot;;    }   </strong></span> </span>

This is a very short function. I won't go through what everything does now, but it shows you that they have the name of the function in the top line. The body of the function is the section inside the curly brackets. This is the code that is run when this function is called.

Ok, now ignore that function completely, since I was just using it to show you what functions look like. The function we are looking for is called ClientConnect, and it starts on line 225. It looks like this:

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   /*    =============    ClientConnect    Called when a client connects to the server    =============    */    void ClientConnect (void)    {    ClientInRankings();    bprint (&quot;^4&quot;,self.netname);    bprint (&quot; connectedn&quot;);    stuffcmd&#40;self, strcat(&quot;exec maps/&quot;, mapname, &quot;.cfgn&quot;&#41;);    // send prediction settings to the client    stuffcmd&#40;self, strcat(&quot;cl_movement_maxspeed &quot;, ftos(cvar(&quot;sv_maxspeed&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_maxairspeed &quot;, ftos(cvar(&quot;sv_maxairspeed&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_accelerate &quot;, ftos(cvar(&quot;sv_accelerate&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_friction &quot;, ftos(cvar(&quot;sv_friction&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_stopspeed &quot;, ftos(cvar(&quot;sv_stopspeed&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_jumpvelocity &quot;, ftos(cvar(&quot;g_balance_jumpheight&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_stepheight &quot;, ftos(cvar(&quot;sv_stepheight&quot;&#41;), &quot;n&quot;));    stuffcmd&#40;self, strcat(&quot;cl_movement_edgefriction 0n&quot;&#41;);    }   </strong></span> </span>

The section at the start inside the /* and */ is a comment. This is ignored entirely by the compiler, it's just there to make the code easier to read and understand for people editing the code. As it tells you, this function is called when a client joins the server. This is the perfect place for us to put our Message Of The Day, since we want it to shown to the player when he joins the server. At the end of the function, just before the final }, add the following line:

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   centerprint(self, &quot;Welcome To My Mod Server!n&quot;);   </strong></span> </span>

I'll go through what this line does. Firstly, centerprint is a built in function of the engine, used to print messages in the center of a player's screen. self is a variable which here points to the player who just connected to the server, so that the engine knows who to show the message to. self can actually refer to any entity in the game. An entity is an object, whether it be a player, an item to pick up or a rocket in the air. In a weapon firing function, self will refer to the player who fired the weapon etc. It's a very useful variable for many situations, and you'll be using it a lot from now on. The "Welcome To My Mod Server!n" is obviously the message we want to be displayed. It is in speech marks, as all text in QC is. It is what is known as a string, but more about that on a later date. The n part probably had a couple of you fooled. No, that won't bve shown onscreen, it's a code used to tell the engine that that is the end of the line.

The whole line is what is known as a function call. centerprint is, as I said, a built in function of the engine. We are calling it to tell it to print our message. The way functions are called is the same whether they are builtin functions defined in the engine, or functions defined in the QC, like ClientConnect. To call a function, you do this: (don't actually add this to the code, it's just an example!)

         <span style="font-size: small; font-family: Verdana">
<span style="font-family: System; color: #ee9977"><strong>   functionname(parameter1, parameter2);   </strong></span> </span>

functionname is obviously the name of the function, whether it be centerprint or whatever. The brackets are what tell the engine it's a function call. There can be any number of parameters, depending on the function. Some have none at all, whereas some have many. Parameters are the information you feed into the functions you call, for example in our code we gave self and our message as parameters to centerprint.

You've probably noticed that most lines of code seem to end in a semicolon. This tells the compiler that it has reached the end of a command, and it will complain and refuse to compile if they are not all in the right places. I forget them on a regular basis, and luckily the compiler tells you exactly what line and in which file you've missed one out. Good boy compiler, have a bone.

Speaking of compilers, save cl_client.qc and run QCC2.EXE. Assuming it compiles without any errors, have now compiled our Message Of The Day mod. Next we'll want to run it.

There are two ways to run your mod, and they require you to set things up differently. They also have their own advantages and disadvantages. The first method, which we're currently set up for, is this: Run nexuiz from the console, with the command:

nexuiz -game mymod

Now start a new server, and see your message when you join :)

I'll explain how to do the other method for running mods and the pros and cons of each method in the next tutorial.

I think that's about it for today. We haven't actually done much coding, but I hope I've started to give you an understanding of how QC works. Next time we'll try something a little more ambitious, but I wanted to keep this first lesson very simple. So now you can have a Message Of The Day in your server. If you change it to say "MauveBib Sucks!" I'll eat your face again.

This tutorial was brought to you by MauveBib, the letters Q and C, and the number 1.


Any questions or comments can be emailed to me at: skinski@email.com

Visit the Electronic Liberation Front website for all my Quake mods at: Planetquake.com

Find me on IRC at: irc.gamesurge.com #nexuiz or #elfteam

I can also be reached by pidgeon post, stripogram and telepathy

Thanks for reading, enjoy yourself

- MauveBib


This comment is currently awaiting admin approval, join now to view.

Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.