Quake Info Pool - Classic Quake - QuakeC Infos & Hints

Back | Last changes: 1999-11-07 | Contact Maddes

# QuakeC Infos & Hints

## QuakeC categories: Infos & Hints / Fixes / Workarounds / Enhancements

(discontinued, check out URQP source for more information)

## Index

- About QuakeC
- About the other persons
- Hints for QuakeC
  - Bugs known by id
  - Source organization for normal Quake and QuakeWorld
  - Include your source
  - Compilation
  - Using console variables
  - Info about cvar() and cvar_set()
  - Use of bit flags in console variables
  - Impulses
  - Impulses on dedicated server
  - Rejecting client-side bots
  - Tips to avoid ghosts
  - Infos about SVC messages
  - Angles
  - Multiplayer testing on one machine
  - Eprint function as a developer message

## About QuakeC

As the name says, it's a C-like language for the quake engine. The source code will be "compiled" and then interpreted when running Quake.

The central for all QuakeC files, which normally end with ".qc", is "progs.src". It lists all the files in the order they'll have to be compiled by the compiler ("QCC"). You should also describe your modifications here, who did it, when was it startet/done, a short description of the patch and which file were added/modified for what reasons. This will help you and many others to understand your modifications even after some months.
The comment should look like this:

    "Progs.src"

    // 1997-12-24 Message Of The Day (MOTD) by Maddes
    //            modified files...
    //              defs.qc      for variable definition and function declaration
    //              client.qc    for displaying MOTD after level changes
    //            added files...
    //              motd.qc      for printing function of MOTD

Also added files have to be named in "progs.src", otherwise they will not be compiled. I recommend to put added files at the end of the file. This helps to make sure if one of your new files or a modified one is making problems when compiling.

Don't forget to declare new functions and define new variables in "Defs.qc", which are used in other/previous files.

Go to Inside 3D to read more about QuakeC patches and to find useful links.
To use the fixes create a subdirectory within your QUAKE directory (e.g. QUAKE/URQP) and put the compiled QuakeC source ("progs.dat") in it. Don't forget to start quake with the "-game" parameter (e.g. "-game URQP").
The following pages contain a lot of bugfixes for Quake, which are implemented in my own addons. I suggest to base your own addons on URQP. Otherwise you should include some of the useful enhancements of URQP (e.g. custom gravity, map rotation or skin support).
Download the "Ultimate Regular Quake And Scourge Of Armagon Patch" now. You get a "Pak0.pak" file which contains the compiled QuakeC source ("progs.dat"), 32 player skins with corresponding head skins and a zip file with the source.
Not included is Robert "Frog" Field's workaround for dead bodies with color and the "Invalid skin #<number>" message.

## About the other persons

Robert "Frog" Field from Australia
...is a very experienced Classic Quake programmer. His current project (as of 1998-07-03) is the FrogBot, which can be found on Metropolis: Frogbot homepage.

Daniel "Athos Kryn" Olsen
...is the author of the ACHE mod for Quake, which provides a modified SinglePlayer and deathmatch mode (expierence level based) with lots of nice little features. Check out his homepage The Throne Of Iron.

Yun Zheng "Zhenga" Hu from the Netherlands
...is only 15 years old (as of 1998), but has a good analytical mind and helped me out with some bug fixes.
He lost his own modification through a harddisk crash, and it was not posted on the net :(

Carl "Lord Sméagol" Lloyd-Parker
...is the author of the Battler addon. He is a totally mad genius in QuakeC and his source looks as insane as Frog's one.

## Hints for QuakeC

Bugs known by id
Search for "FIX ME" and "FIXME" within the original code and you will find some things which could be made better.

Source organization for normal Quake and QuakeWorld
Always keep your source for NQ and QW in separate subfolders of your addon. Use SRC for the NQ source and QWSRC for the QW source. Make sure that the first line in progs.src of your QW source is "../qwprogs.dat" (please note the double points).

Example directory structure:
(X: is the drive you installed Quake to)

- X:\quake
  - id1
  - newaddon (will contain progs.dat and qwprogs.dat after compilation)
    - src (with many .qc files and one progs.src file for normal Quake)
    - qwsrc (with many .qc files and one progs.src file for QuakeWorld)

Include your source
It's always a good idea to include the source in the package (e.g. as a zip file within the package) or release it seperately. This way the source never gets lost, also people can learn from your source, can fix bugs themselves and hence help you to reduce your workload.

Compilation
To compile an addon, go to its source directory and call QCC. Make sure that QCC is in your path or within the source directory.
If you get errors then fix the first error and recompile, because the other errors are normally follow-up errors.
I recommend to use Mr. Elusive's MEQCC instead of id's original one, because it compiles faster, has stronger syntax and function call checking, supports compiler directives and much more.

Using console variables
If you want to use console variables for your own modifications, you should use the following cvars first: GAMECFG, SCRATCH1 - SCRATCH4, SAVEDGAMECFG and SAVED1 - SAVED4.
Remember these are only available in Quake 1.07 or later, so you should point this out in your readme.
All the cvars beginning with "SAVED" will be stored in "config.cfg".
Other console variables you can use are: TEMP1, and maybe even TEAMPLAY, NOEXIT and SAMELEVEL if you really need them. REGISTERED would be another good cvar, but it is set to 0 or 1 through the engine on startup, maybe just ignore this bit.
If you use one of these, then make sure you correct the already existing code for them, e.g. you should remove the use of TEMP1 in "PlayerDie()" ("Player.qc").

Info about cvar() and cvar_set()
Both functions always access the console variables of the server, not of a client machine.
If you use cvar_set() in an impulse function, take care as clients change the variable on the server.
And remember the cvar name hos to be in lower case.

Use of bit flags in console variables
Console variables can only be accessed through the "cvar()" function as floats. Floats have 24 bits for the mantissa (base value), 7 bits for the exponent and 1 sign bit. Therefore, using values greater 16777215 (0xFFFFFF) will lose access to the least significant bits. This limits their use to 24 bit flags which can be easily set by the server admin, otherwise you had to do some calculations just to get 7 or 8 more bitflags.
Thanks to Daniel "Athos" Olsen and Carl "Lord Sméagol" Lloyd-Parker for the information.

Impulses
Impulses in Quake only range from 0 to 255. Higher values are masked with 255, so "impulse 270" will be 14 in QuakeC.
Impulses in ImpulseCommands() are not always executed immediately because of the attack state of the client. If you want impulses, which do not alter the weapon/attacking handling, to be executed immediately then you have to add an additional Impulse function to the PlayerPreThink function (see URQP 1.05).

Impulses on dedicated server
Impulses are not available on dedicated servers, you should use console variables for server settings.

Rejecting client-side bots
If you want to avoid players using client-side bots with your addon, just print "No Bots Please" as a center message when the client connects. An example how to do this can be found at the "The Message Of The Day" code.
A fair and correct programmed client-side bot will disable itself. Also those bots should put a "[bot]" (or similar string) at the end of the player's name to indicate that the player is using a client-side bot.
The message doesn't help when the player "hacked" or modified the bot :(

Tips to avoid ghosts
Tip by Daniel "Athos Kryn" Olsen:
The problem lies in the value of ".float dead_flag". If this value is not "dead_respawnable" the player will not be able to respawn. The value of ".float dead_flag" for the player is "dead_dead" until the end of his death frames, this is to avoid players respawning while the death frames are happening and to avoid weird looking old dead bodies lying around.
The following happened in an earlier version of my ACHE mod when a player discharged the thunderbolt, then "SetCurrentAmmo" is called to switch to the next weapon in line, because the player lost all cells. The problem is if the person dies, but does not gib, the "player_run" function in the beginning of "SetCurrentAmmo" resets the player frames. If the player does gib ".void th_run" is set to "SUB_NULL" by the "throw_head" function, the player's deaththink keeps active and everything works fine.
A possible allround fix could be (crossed fingers):

    "Weapons.qc"

    void() W_SetCurrentAmmo =
    {
    	if (self.health > 0)	// added by Athos...fix for "ghosts" (fingers crossed)
    		player_run ();		// get out of any weapon firing states
    ...
    };

Cronos of the CronosBot used the following statement:

    ...
    	if(self.deadflag >= DEAD_DYING)
    		return;
    ...

Cronos' workaround looks more correct to me, but maybe it should be written the following way:

    ...
    	if(self.deadflag != DEAD_NO)
    		return;
    ...

And for safety issues you could also add:

    ...
    	if (self.health <= 0)
    		return;
    ...

Infos about SVC messages
If you are interested in Quake's SVC messages then check out Uwe Girlich's DEM/QWD specs.

Angles
Angles in Quake are always positive and range from 0° to 359°. Use the "anglemod()" function to get a "normalized" angle from positive and negative angles.

Multiplayer testing on one machine
Tip by Carl "Lord Sméagol" Lloyd-Parker:
You can run WinQuake three times in windowed mode on one machine, this is useful to test multiplayer issues.
Warning!!! Sometimes Windows does not like this and crashes, so make sure you have saved your work before using this tip.
Here's how to do it:

1. WinQuake -listen 16 +color 3 +name Server +map dm4
2. WinQuake +color 4 +name Client1 +connect <IPX>
3. WinQuake +color 12 +name Client2 +connect <TCP/IP>

Eprint function as a developer message
If you want an eprint function as a developer message use the following, but be careful as eprint functions are the only way for the user to tell you which entities caused a problem.

    if (cvar("developer"))
    	eprint(entity);

a Quake Info Pool page
© 1997-2022 by Maddes