For more infomation about the comm engine of how to write agent code I can be reached at tlane@cc There are samples of both active and event driven behaviors in /vrmidtown/vrmidtown/testclient/remoteview/viewer.c you can do a search for "myagent" and it should give you all the relevant code. Event driven agents wait for events then do somthing for example when viewer.c recieves "come" it goes to where the agent who sent that msg is Active agents can do things without ant specific direcives to prevent these agent from timing out any active agent code must be run in a thread. You need to run these types of agent in a thread because the graphics engine also needs to draw the screen while you are "thinking". Since the graphics engine will be running constantly, but you may not have an active agent running you will need to run them in thread. Since the "thinking" you are doing is taking as much time as the graphics thread you will slow the graphics engine to a crawl I got around this by using usleep() which tells the thread to sleep for a cretain amount of time. I also used the sched_yield() function when I wanted to be sure that the graphics engine did something in between two actions. Take a look at the myagent_activeAgent which is commented out in the main. When run this function runs another function in a thread which makes the agent turn toward anyone who comes within 50 units. Multiple agents within 50 units will probably cause problems. The major differences between active agents and event driven agents if wether they have to use update functions or not. Active agents becuase they run in threads do not need to explicitly run update functions (commUpdate, display, etc) in fact, running them tends to cause the agent to crash. Event driven agents on the other hand must run update functions so that the changes they make do not appear in one large jump. If you can manage it even event driven agents should be run in threads so that there are no update problems. Note that the command come seems to come to where you are then turn to face you, while the code indicates that the agent turns to face you then comes to where you are! This discrepancy is because certain openGL structures are not updated until the agent is finished. Take a look at the myagent_lookAt and myagent_goto functions for samples of running update functions. data structures: to modify your agent you need to kwon about about two different data structures eyePoint[] and dirVec[] both of these are arrays of 3 floats (IRC). eyePoint is where you are and dirVec is a diretion vector of your facing while dirVec does not need to e length 1 to get the facing correct it does need to be lenght 1 to handle movement properly Also note that thse structures are not what is really used to draw the agent to the screen. Those structures are openGL structures that are more difficult to deal with. Thus to see an actual change in the agent you must run some of the graphics update funcitons. the comm pointer stores both all the agents that this agent knows about (comm->world->agentList) and the agent that is running in this client (comm->ourAgents) The agentList holds data on the position and orientation of all agents that the local agent knows about. Take a look at the agent_t data structure for details. Most active agents must make loops through agentList to be "aware" of what is going on in the world. When running active agents tell the thread running the agent code to yield (sched_yield) and sleep (usleep) because it will bring the viewer to a crawl if you don't. the samples should give you some idea of how long to sleep to keep things moving at a reasonable speed (at least on the O2s in the GVU :) I have not experimented much with the sleep times so there is proably room for improvement here. If you know more about pthreads then you can implement thread priority, but I don't know how to do it. Due the fact that the sample agent code acesses many global variables used in the viewer I was not able to move it out of the viewer and into its own file. However, a search for "myagent" ("/myagent" in vi) will turn up where all the agent code is. Also note that the functions that implement chatting are in the "chat_functionname" funcitons. Also not ported out to another file. The viewer in /vrmidtown/vrmidtown/testclient/viewer does almost straight chatting if you wonder how it works. The viewers refered to here is not the latest version of the graphics viewer (which is in vrmidtown/vrmidtown/client/viewer). However, to make the viewer threadsafe, most of the error messages in glm3d.c must be suppressed. Since the graphics engine is still under development these error messages cannot be suppressed in the current version. Addendum: there may be a workaround on this, check the mailing list for updates. Note that named agent create was also added to these viewers. They make references to the createAgentWithId event in the server in ""/testserver. To run the discussed clients: "client.sh" for usage. Note that these are the shell files in the same directory as viewer.c To compile "make -f Makefile.irix" will compile most parts of the code for irix machines. The Makefile.generic file hold the actual list of files to be complied.