Changes between Version 1 and Version 2 of ioquake3


Ignore:
Timestamp:
Jun 21, 2011 1:39:35 PM (13 years ago)
Author:
jpawlick
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ioquake3

    v1 v2  
    11The following is what I've learned about the ioquake3 engine, which I hope will be helpful to you guys while I'm away.
    22
     3== General Terms ==
     4=== Frames ===
    35
    46== Server, Client, Interface ==
     
    3335in your AINode function. Remember that anything compiled inside the virtual machine must be in (a restricted form of) ANSI C90, so all variable declarations must be at the beginning of compound statements, etc.
    3436
     37Your AINode function should fulfill these requirements:
     38 * When the behavior is finished, the function should call AIExit_Quagents. The parameters you should pass to this are (1) the botstate, (2) the id of the command (this is cmd->id), (3) the value of your command macro (usually easiest to just do cmd->command), and (4) a string stating the return status ("done" for normal execution, or a meaningful error message (no spaces allowed) otherwise). After exiting, the function should return qfalse so that the next command on the command queue is handled.
     39 * When the function has run everything it can this frame but the behavior is not finished (has not called AIExit_Quagents), the function must return qtrue, else the function will be called again.
     40 * All current Quagent-specific AINodes are named AINode_G*, where * is the task name. The G is for quaGent, and is there to prevent collision with Quake's built-in AINodes.
     41
     42==== BotQuagentAILatentNodeHelper() ====
     43Some Quagent behaviors require updates after the movement portion of the frame has been executed. However, because the user may interrupt the action with another, the functions cannot rely on being called again on the next frame (because a different command may be executed), and there is never a guarantee that they will ever be called again (for example if the user commands a "n [[fa]]", all previous interrupted behaviors are never resumed). For some behaviors (usually ones that track progress of movement), this is unacceptable, so part of their functionality is defined in BotQuagentAILatentNodeHelper() in game/ai_main.c. This function is called every AIFrame, and usually updates a progress value for whatever behavior was active in the most recent frame and then clears its memory of which were active.
     44
     45If you examine the function you'll see that it updates the values pointed to by pointers in bot_state_t. These pointers point into the commandqueue, at elements of a quagent_command_t. Under our design, a quagent command must store all progress and state information into its quagent_command_t. This is because multiple commands of the same type are allowed to be on the queue, so per-type storage won't work, and because the queue has already allocated space for storing their parameters.
     46
     47Take [[mb]] as an example (AINode_GWalkBy is the function). A moveby command attempts to move the bot in a specified direction for a specific distance. However, it is difficult to tell how far exactly the bot will move on a given frame, so what the function does is update a pointer in bot_state, merely request a move, return, and then when BotQuagentAILatentNodeHelper is called on the next AI frame, it figures out how far the bot has moved and decrements the moveby distance by that amount. So on the first frame, the distance may be 50, but on the second, it may be 41, then 22, then 2, then -5. When it becomes negative the bot enters a "backpedaling" scenario, and (if on the ground) teleports back to where it should have moved to.
     48
     49==== Thread Safety ====
     50Thread safety is not a concern because Quake is single-threaded. If a user sends a command while an AINode is midway through execution, it will not be read until the next AI frame. You are guaranteed that the state of the command queue is constant through the execution of an AINode. For this reason, it is safe to make multiple calls to trap_Com_QuagentsWriteStr, as the batch rangefinder does.
     51
    3552=== ai_main.c ===
    3653TODO: put text here.