excution order

Discuss programming in the QuakeC language.
Post Reply
goblinoid
Posts: 22
Joined: Fri Mar 21, 2008 9:28 pm

excution order

Post by goblinoid »

Hi,

I have a doubt, in which order the engine executes the functions written in qc?

Thanks
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Post by ceriux »

um explain your problem more please...
Urre
Posts: 1109
Joined: Fri Nov 05, 2004 2:36 am
Location: Moon
Contact:

Post by Urre »

He's being pretty straightforward. I don't quite know the answer though, I'm also interested.
I was once a Quake modder
metlslime
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Post by metlslime »

He probably means like, touch functions, think functions, spawn functions, etc. I think the answers are (please someone correct me):

- spawn functions are executed in the order the entities are listed in the BSP file

- think functions, for all entities that need to think during the same server frame, are executed in order of edict number

- touch functions are executed like this: physics are run on entities in order of edict number, and if an entity touches another entity during the physics move, its touch function is called immediately, then the entity it touched is called right after that.
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Post by ceriux »

wouldnt is problem be posted in the engine section then?
Wazat
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Post by Wazat »

Not really. This order is very relevant for qc coding. It's sometimes important to know what order certain QC functions will be called (for example, worldspawn always goes first, then other spawn functions).
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
goblinoid
Posts: 22
Joined: Fri Mar 21, 2008 9:28 pm

Post by goblinoid »

ceriux wrote:um explain your problem more please...
I'll try...

In C programs there's the main function that's the first to be called and dictates when/if the other functions are called (well, I'm not really a programmer, so this can be incorrect). In QC, we define lots of functions, that usually call or are called by other functions, but I can't realize which one is the first to be called. Is there a main function anywhere? Is there a standard order of function calls?

Thanks!
Last edited by goblinoid on Sat Dec 19, 2009 4:03 am, edited 1 time in total.
MeTcHsteekle
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Post by MeTcHsteekle »

i always imagined it as a action/reaction thing where the first one gets called and fires off others which fire of others and they all branch out

kinda like nuclear power i suppose

but that's just what i thought
bah
goblinoid
Posts: 22
Joined: Fri Mar 21, 2008 9:28 pm

Post by goblinoid »

MeTcHsteekle wrote:i always imagined it as a action/reaction thing where the first one gets called and fires off others which fire of others and they all branch out

kinda like nuclear power i suppose

but that's just what i thought
So do I. And that's probably true for most of the functions, but I don't think the engine calls only one function that starts it all, I also think there might be some sort of loop that executes PlayerPreThink and PlayerPostThink, and probably other functions, over and over again. But that's only my hypothesis. I hope someone can make this clear...
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Post by ceriux »

i look at it like a list.

the order in which they're called are in the progs.src and i imagine most functions are just called as the game reads out the order of the qc files listed in that progs.src minus a few like client connect, and playerpost(pre?)think.

basically i feel they're called either when they're told to, when they're supposed to or as they're hit in the list specified in the progs.src although i may be wrong. but thinking like that has helped me so far when coding for my mods.
goblinoid
Posts: 22
Joined: Fri Mar 21, 2008 9:28 pm

Post by goblinoid »

I think progs.src just tells the compiler in which order it should read the .qc files...

Ok, found that on QuakeC Specs:
7.3 Mandatory functions

These functions must be defined in Quake C, since they are invoked by Quake under certain conditions.
Misc

void main();

Only used for testing progs.

void StartFrame();

Called at the start of each frame.
Behavior of players

void PlayerPreThink();

Called with self=player, for every frame, before physics are run.

void PlayerPostThink();

Called with self=player, for every frame, after physics are run.
Management of network game clients

void ClientKill();

Called when a player suicides.

void ClientConnect();

Called when a player connects to a server, but also, for every player, when a new level starts.
It is used to announces the new player to every other players.

void PutClientInServer();

Call after setting the parm1... parm16.

void ClientDisconnect();

Called when a player disconnects from a server
Announce that the player has left the game.

void SetNewParms();

Called when a client first connects to a server. Sets parm1...parm16 so that they can be saved off for restarts.

void SetChangeParms();

Call to set parms for self so they can?
I think they forgot worldspawn here.

Also:
4.1 Running Quake-C code

Here are some more remarks from John Carmack:
Code execution is initiated by C code in quake from two main places: the timed think routines for periodic control, and the touch function when two objects impact each other.

Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
So I supposed the order's like this:

ClientConnect
Worldspawn
Entities spawn functions (or would it come after parm functions?)
SetNewParms
PutClientInServer
StartFrame
PlayerPreThink
everything else
PlayerPostThink
repeat the last 4 for every frame

and eventually
ClientKill
ClientDisconnect
SetNewParms

Is this right? Perhaps an engine coder can answer.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

if you depend upon the order, you're doing something wrong, tbh.
Okay, so you can depend upon prethink being called before think before postthink, but you can't depend upon one player's postthink being called before the next player's prethink if you care about DP compatibility.

ClientConnect happens after the world has spawned and run its first physics frame. Even without seperate client+server.

SetNewParms should *NEVER* do anything that even remotely depends upon execution order.

Touch functions happen when other entities touch self. That is, you cannot depend upon touch/think ordering.

For players:
SetNewParms
ClientConnect
PutClientInServer
repeat:
PlayerPreThink
think
PlayerPostThink
with periodic:
ClientKill / KRIMZON_SV_CLIENT_COMMAND stuff.
when they leave:
ClientDisconnect

In NQ, players get thier think functions called before other ents in the frame, but that's not often relevent unless perhaps you want to make a bot that works with mods that depend upon that ordering. Players will have their think functions called between the think functions of other ents - but only if the nextthink times are always the same. Unless the server supports prediction, in which case any assumptions based upon player/non-player thinks will break your mod.

Simply put, if the ordering of function calls is not given by the names of the functions themselves, then you're doing something wrong which will break at some point.
goblinoid
Posts: 22
Joined: Fri Mar 21, 2008 9:28 pm

Post by goblinoid »

Thanks Spike, that explains pretty much everything

I'm not doing anything that really depends on the execution order, I'm just trying to figure out where the code brakes. Apparently it's somewhere near PlayerPostThink, but I've read the code hundreds of times and couldn't find the error. I don't know if the problem is in PlayerPostThink itself, one of the functions called by it, or the next function executed by the engine (that would be StartFrame, right?). So I decided to read the code following the execution order (I also got curious about how the engine operates). That's probably not the best way to find the problem, but it's the best I can do with my (in)experience.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

for players specifically, you have:
if(retouch)triggers.touch
playerprethink
self.think
solids.touch
triggers.touch
playerpostthink

order obtained from fte, but from the NQ pathways, so it should match up closely enough with NQ engines.
Sajt
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Post by Sajt »

The other entrypoint for QC code are the entity spawn functions. monster_army, info_player_start, and the like. When the engine loads a map, it takes each entity defined in the map, and looks for and executes a QC function with the same name as the entity's classname field.

The spawn functions are (like metlslime said) called in the order that the entities are defined in the map, that is, the order should be treated as 'undefined' by the programmer. If you have an entity that needs to find another entity at the start of the map (i.e. a teleport looking up its destination), you have to delay that by 0.1 or 0.2 seconds, when it's ensured that all entities will have been spawned (the Quake progs do this often).

The exception is the worldspawn entity (yes, worldspawn is not a special function, just another entity). worldspawn is (I THINK) always the first entity in the map, so its spawn function is always executed before those of any other entities. In fact, it should be the very first QC code executed in all cases (except loading a savegame). Which means that you can do all 'initialization' stuff in worldspawn.

And the entity spawn functions are only called on the 'map entities'. They aren't called when you spawn an entity with code (using the spawn() function).
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Post Reply