
********************************************************************
NOTE!
This setup assumes that directory "source" is placed in "c:\quake3\"
********************************************************************

These instructions cover downloading and compiling only the .qvm files for Quake 3 Arena 1.32b source code.  
This does NOT cover the full 1.32 Quake 3 engine source as that requires Visual Studio, though these instructions 
can be adapted for compiling .qvm files from that source as the process is the same, though the directories may 
differ.  Most modders will not be performing modifications to the engine, and those that would don't need these 
instructions anyway.  This is meant for those new to modding that don't know how to get Q3 to compile and contain
some information I had to learn the hard way.  These instructions assume that you are using Windows 7. 
Some steps may differ for other versions of Windows, and I have not tested any of this on Windows 8.x or 
Windows 10.  This has been tested successfully on Windows XP 32-bit, Windows 7 Ultimate 64-bit, and should 
work fine on 64-bit XP and 32-bit Windows 7 as well.

First, you'll need the Quake 3 Arena 1.32b source code.  This can be downloaded here:
ftp://ftp.idsoftware.com/idstuff/quake3/source/Q3A_TA_GameSource_132.exe

Run the program.  Click through the "next" and click "yes" to the license agreement.  It will ask to use this 
as the default directory:

c:\quake3\source\

Use that directory, NOT your Quake 3 Arena game directory.  This directory is where your source code will go for 
editing.  Once installed, click Finish and close any remaining windows.

You should now see a quake3 folder in your C:\ drive.  Open it, and you will see a "source" folder.  
This folder will contain the following subfolders:

bin:  This contains four programs:  lcc.exe, q3asm.exe, q3cpp.exe, and q3rcc.exe.  These programs are what compile, link, and assemble the .h and .c source files into the .qvm files.

code:  This contains four subfolders with the actual source code:
- cgame - This contains the source for the cgame.qvm module.
- game - This contains the source for the qagame.qvm module.
- q3_ui - This contains the source for the ui.qvm module used by Quake 3 Arena but NOT by Team Arena.
- ui - This contains the source for the ui.qvm used by Team Arena ONLY.
There is also one file in here:  quake3sdk.dsw.  You do not need to do anything with this file.

lcc:  This contains data for the lcc compiler.  You should not modify anything in this folder.

q3asm:  This contains the source code for the q3asm assembler program. You do not need to do anything with this.

ui:  These are menu files used by the Team Arena user interface.  You do not need to modify anything here unless 
you're planning on modifying the Team Arena menu system. Instructions for the Team Arena menu system will not be 
covered here.

The very first thing you want to do after installing is BACK UP THE ENTIRE SOURCE FOLDER.  
Just copy and paste it somewhere and call it "source_clean_backup". This way if something catastrophic happens 
to your source code you have a 100% clean and unmodified source, along with the compiling utilities, without 
having to download it again if you misplace the installer.

**********************************
**** START: Special attention ****
**********************************
We need to have certain programs always accessible to the system. This is done by creating or modifying a system 
environment variable called "PATH".  The "PATH" variable tells the system where to look for a program or file if 
it is not in the same directory you're trying to run it from.  It will look in each directory listed in the 
"Path" variable in order.  We need to add a few lines to this so the code can compile. Here's how to do that.

Find "My Computer" on your desktop and right click on it, then click "Properties".  Click "Advanced System 
Settings" in the left column.  In the "System Properties" window, click on the "Advanced" tab, then click 
the "Environment Variables" button.  In the bottom window, scroll down until you see the word "path" on 
the left side of that window. Click to highlight the "Path" line, then click the "Edit" button on the 
"Environment Variables" button.  If you're going to do a lot of editing and have a slower hard drive it may 
be a good idea to add the new variables at the beginning. You need to separate each new directory with a ; and 
you cannot use spaces.  DO NOT remove anything already in this variable or your computer might not like it!  
Add this line to the variable:  C:\Quake3\Source\bin

All the files in the source code are set to "read only" be default, so we'll need to change that.  Right click 
on your "code" folder.  Click on "Properties".  Uncheck the "Read Only" box.  Click "OK".  It will ask you if 
you want to apply the changes to this folder as well as any subfolders and files. Make sure subfolders and 
files is selected.  Click on "OK".  Now we can modify the source code.

Next, we need to edit the .bat files that compile the source so they pause after running.  If not, 
the command window will close and we will not be able to see if there was an error in compiling or if it 
was successful.  Go to the "cgame" folder in your "code" folder.  Right click on cgame.bat. In the menu, 
click on "edit".  Scroll all the way to the bottom, and you should see the following lines:

q3asm -f ../cgame
:quit
cd ..

Add this word beneath those statements: pause

Save and exit the editor.  You will need to do this to the game.bat in the "game" folder, and the q3_ui.bat in the "q3_ui" folder.

We are now ready to do a test compile!
First, go to the "game" folder and double-click on game.bat.  It should run for about 1 second, printing a lot of statements in the command window.  When it's done it should report 0 total errors, and end with "Press any key to continue".  If you want to you can scroll up the command window and see what the compiler was doing.  Once you're done looking, press any key to close the compiler window.
Repeat this for the q3_ui.bat and cgame.bat files.

********************************
**** END: Special attention ****
********************************

If no errors were present, we should now have several files located in C:\quake3\baseq3\vm\ as follows:

cgame.map
cgame.qvm
qagame.map
qagame.qvm
ui.map
ui.qvm

The .map files are only useful to mappers if you're introducing new map entities, surface types, or brush types.  Those can be ignored or deleted as desired.  They will show up every time you compile.

The .qvm files are what we're interested in.  We need to get those into a .pk3 so Quake 3 Arena can use them.  .pk3 is actually just the .zip format used by Winzip renamed to .pk3.  In the baseq3 folder, go to the "File" menu, click on "New", and click on "Compressed (zipped) folder".  Name this "pak9.zip".  Right click the "vm" folder.  Click "copy" from the menu.  Double click the "pak9.zip" folder to open it.  Click on the "Edit" menu, and click on "Paste".  If you prefer you can delete the .map files, though it is not necessary.  Go back to your "baseq3" folder.  Rename "pak9.zip" to "pak9.pk3".  Windows will warn you about renaming the file.  Click on "Yes".  Windows will not understand the .pk3 extension, so any time you need to edit a .pk3 just rename it with a .zip extension and you can see inside the archive.

Now the we have our compiled source in a .pk3 archive, we need a mod folder to work with.  Locate your Quake III Arena game folder.  Create a new folder named "mymod" (or whatever you're calling your modification).  Copy your pak9.pk3 file into this folder.  Next, we need a description for this so Quake 3 can list it in the mods menu.  Create a new .txt file in your "mymod" folder and name it "description.txt".  Type in your mod's name.  You can use Q3-style colors to highlight it, such as ^4mymod^7 to give it some color.

Now you can load Quake 3 Arena and select your mod from the list!  That's it!

* Some notes about .qvm files

.qvm stands for Quake Virtual Machine.  These are platform-independent compiled code files, meaning that they can run on any operating system - Windows, Linux, OS-X, etc, because they're accessed directly by Quake3.exe and Quake3.exe handles any system calls to the operating system.  There are three .qvm files:

qagame.qvm - handles all server-side operations.
cgame.qvm - handles all client-side operations.
ui.qvm - handles the user interface.

A dedicated server will ONLY load qagame.qvm.

A client connecting to a dedicated server will ALWAYS load ui.qvm and cgame.qvm, but not qagame.qvm.

A local game, such as single player, skirmish, or hosting a server that is not a dedicated server will load ui.qvm, qagame.qvm, and client.qvm.

The load order for a client connected to a dedicated server is always ui.qvm first, then cgame.qvm.

The load order for a client running a local server is always ui.qvm first, qagame.qvm next, and cgame.qvm last.

** Some notes about compiling

There are a few files that should never be modified.  In the "game" folder, do NOT modify the following files.  If you delete or edit any of these files Quake 3 will either fail to compile, your mod will act erratically or will CRASH.

In the "game" folder, do NOT modify any of the following:

bg_lib.c
bg_lib.h
game.def
game.dsp
game.q3asm
g_syscalls.asm
g_syscalls.c
q_shared.c
q_shared.h
surfaceflags.h

In the "q3_ui" folder, do NOT modify the following

q3_ui.def
q3_ui.dsp
ui.q3asm

In the "code\ui" folder, do NOT modify the following:

ui.def
ui.dsp
ui.q3asm
ui_syscalls.c
ui_syscalls.asm

In the "cgame" folder, do NOT modify the following:

cgame.def
cgame.dsp
cgame.q3asm
cg_syscalls.c
cg_syscalls.asm
tr_types.h

In the "game" folder, there are several files that begin with bg_ such bg_pmove.c, bg_public.h, etc.  These files are shared across qagame.qvm, ui.qvm, and cgame.qvm.  If you modify any file starting with bg_ you MUST compile ALL THREE .qvm's.  If you do not, the server and client logic will be out of sync with each other and it can affect some screens in the UI as well.

For example, say you change the player jump velocity in bg_pmove.c, then compile qagame.qvm and you forget to compile cgame.qvm.  You then run a dedicated server and add some bots.  You then connect to that server.  The server's logic will have the bots jumping with the velocity that was compiled into qagame.qvm.  Your predicted velocity on the client side will be what was compiled into cgame.qvm, so when cgame receives a "jump" command from you it will be running the wrong math - not allowing you to jump as high as the bots.

*** .pk3 file notes

.pk3 files can have any alphanumeric name permitted by windows, but Quake 3 has a specific order in which it loads them.  The order is alphanumeric.  pak8.pk3 will load before pak9.pk3, which will load before qpak.pk3.  If a file in one .pk3 has the same path and name as another, the file in whichever .pk3 is loaded LAST will be the one that is used.

For example, in baseq3\pak0.pk3, there is a vm\qagame.qvm.  In baseq3\pak8.pk3 there is also a vm\qagame.qvm.  The vm\qagame.qvm in baseq3\pak8.pk3 will be the one used by Quake 3 and the one in basq3\pak0.pk3 will be ignored.

This is important for modders to note as any files in baseq3 always load before the mod loads, therefore the .pk3 files in the mod folder will need to be named in such a way that they load after any content in baseq3 that the mod is replacing.

If a replacement weapon model isn't loading or a texture isn't being replaced properly, or your code isn't working, odds are the .pk3 in the mod folder is loading in the wrong order, you did not include the proper folder path inside the .pk3 file, or you forgot to rename the .zip file to .pk3.

.pk3 files CANNOT be nested in each other.  You cannot have a "mymaps.pk3" that has "coolmap1.pk3", "coolmap2.pk3" in it.  Quake 3 will NOT look in any .pk3 that is inside another .pk3.

**** Coding notes

.qvm files are coded in C.  You cannot use any C++ or C# language.

If you don't know what a function does or how it is used, say, RotatePointAroundVector for example, just do a search of the "code" folder.  This will show you what files it's used in.  If you want to see the definition, look at the header (.h) file it's located in, then open the associated .c file.  If you're not sure where it's defined it is probably in bg_lib.c, bg_lib.h, q_math.c, q_shared.c, or q_shared.h.  Don't change those functions.  If you need something similar but different, write your own and put it in a different source file from those.

Some things sent across the network cannot be modified.  Nothing in the playerstate_s or entitystate_s data structures can be changed as the network code expects those to be sent EXACTLY as they are coded.  Some variables in those data stuctures are not always used so it is possible for send a value from the server to the client by "borrowing" a variable, but you're limited on this. 

As for what they do, playerstate_t is ALWAYS accessible by the server's qagame.qvm module.  It is the ONLY way the server sends data about the player entity in the snapshot_t structure on the client (cg.snap->ps) to that specific client.  If you are spectating and following another client, the cg.snap->ps data will come from that client.  On the client side there is also a cg.predictedPlayerState structure.  This holds the predicted player's information as generated client-side.  The local client will always have a cg.predictedPlayerState.  The cg.snap->ps playerstate is what the server is saying about that client.  This is IMPORTANT to note because cg.snap->ps will ALWAYS come from the server and will be subject to packet latency!  You have to decide which one to look at based on whether you want to look at the predicted client or what the server is doing to the predicted client.

Entitystate_t is the data structure sent by the server about all other entities, including other players.  If the player in question is not the local client or a player that client is following as a spectator than the client will NEVER receive playerstate_t information about that player.  The server copies certain data from that playerstate_t and stuffs it into entitystate_t and sends that instead.  That means things such as ammo counts, health, etc, are NEVER sent about other players since that data is not copied over to entityState_t.  This was done to help prevent cheating and also to cut down on network overhead since the playerstate_t structure has more data in it.


If this is confusing, easiest way to remember is this:

On the server (qagame) side:

Anything is accessible.

On the client (cgame) side:

You will always get playerstate about yourself (or a followed player if you're spectating).
You will always get entitystate about other players.
You will never get playerstate about other players.
You will never get entitystate about yourself (it's all in playerstate anyway).

***** Compiling notes

lcc is a VERY basic compiler.  It will tell you what you messed up in what file and what line number, but not much else.  If you see a whole string of errors, odds are you missed a { or } or had one too many of either.

You will have to use your own text editor of choice.  I recommend staying away from notepad.  Wordpad is better, but a text editor that has line numbers is superior.  Also, all code MUST be saved in plain text only without formatting.  If notepad can't open it without showing funny symbols then don't expect it to compile.  If you don't have a text editor with line numbers and you're not sure at what line an error is located, type in a bad control line, such as #@@@@, save your file, then compile again.  LCC will stop with an "Unidentified Control Line" error wherever the #@@@@ is and you'll know what line that is.  Just move this statement up or down in the code and repeat this process until you locate the error.

BACK UP YOUR CODE OFTEN!  Sometimes a simple mistake can take a long time to undo.  When I first started coding I backed up every change I made.  This made it a lot simpler to debug, especially if I missed a bracket.

You can shorten the process of compiling, copying, and zipping your files up if you like by creating .bat files that run all three compiler .bat files, copies your .qvm's into a different folder, and then all you have to do is zip your "vm" folder.  That's up to you.

