It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.    
Latest game industry news.|Articles about game development.|||||Searchable databases of game development companies, products, and web sites.|Purchase stuff from Gamasutra, Game Developer magazine, the GDC, and more.
Search articles, jobs, buyers guide, and more.

By Richard Evans and Thomas Barnet Lamb
Gamasutra
[Author's Bio]
April 24, 2002

The Case for Activity

The Implementation of Activity

Example Activity

Printer Friendly Version
   

This feature originally appeared in the proceeding of Game Developers Conference 2002


2002 GDC Proceedings
CD-ROM
Price: $150.00 + S&H

Letters to the Editor:
Write a letter
View all letters


Features

GDC 2002: Social Activities: Implementing Wittgenstein

The Implementation of Activity-Orientated structure

Requirements for an Implementation of Activities
Our activity implementation must satisfy these requirements

  • It must be easy to add new activities
  • Processing activities must be fast
  • Activities must be easily debuggable
  • The consequential structure of activities must be able to be queried by agents, so that they can determine whether or not it is in their interest to accede to requests.

Already these requirements seem almost incompatible: if activities must be efficient and debuggable, they should be written in C++ so we can use the existing optimisation and debugging tools, but if they are written in C++ it won't be very easy for content authors to add a new activity, because it will require a programmer, and it will be very difficult for the structure of the activity to be exposed to the agents: it might necessitate duplication of information, once to do things, and once to tell the agents what will be done. If, on the other hand, an activity is defined in a text file in a nice easy-to-use language, then content authors will be able to add new activities easily, and the agents will be able to use the information, but we lose the optimisation and debugging tools which C++ gives us. What to do?

The solution we have adopted is to define a new activity in a text-file, in a special-purpose easy-to-use language, but when this activity is parsed, c++ files are generated. This way we get the best of both worlds!


Implementation: Overview
A new activity is defined in a text file. When the activity is parsed, a new c++ activity is defined in cpp and header files. This activity inherits from the base Activity class:


When the activity is parsed, a new c++ activity is defined in cpp and header files..

The alternative to this might be some C preprocessor based technology (Game Programming Gems Vol 1, Section 3.1 - A Finite State Machine Class). This would have the advantages of being simpler (one would not need to write a parser) and one would gain the benefit that the code the debugger debugs would be precisely the same as that the user wrote, rather than merely generated from it. However, this would unacceptably straightjacket us - the preprocessor is a very weak tool. Moreover, writing a parser is not very hard using lex and yacc (note also that the hard part of writing a compiler from scratch, the semantics, can be partly avoided as we build our language on C++ and can leave some of the semantics to the C++ compiler). Moreover, on certain systems, via use of techniques like #line preprocessor directives, the debugger can be made to take the user directly to the appropriate line of the activity file, if the system breaks in an activity.

Activities in More Detail
Now we have decided that a dedicated 'front' to C++ as a form for an activity system, we must ask what form we would like that front to take. The first approximation to an answer would, for most game programmers, be a state machine. State machines have a proven history, and are very useful. However, it turns out to be useful to extend this slightly, to make the states hierarchical, and give states local variables. These are automatically constructed on entry and destroyed on exit. This is very similar to programming using the local stack machines in (Game Programming Gems 2, Section 3.2, Micro-Threads for Game Object AI) Thus an activity defines a state hierarchy:

     activity Name(Parameter1, … ParameterN) {
          State1:
                 State 1.1:
                        …
                        State 1.1.1
                                …
                        State 1.1.2
                                …
                 State 1.2
                        State 1.2.1
          …
     }

Each particular state can have its own parameters, its own preconditions, its own message handling, its own local variables with initialisations, its own actions, and its own sub-states.

Needs
Needs conditions specify what needs to be true for the activity to remain in this state, and what state to switch into if circumstances change. If we are in a particular state, all needs conditions in all parents states are checked before checking our own particular state's. If we have the state tree:

     S1:
          needs 1
          S2:
          {
               needs 2
               ..
          }
     S3:
     …

and we are in state S2, then needs1 will be checked, followed by needs2.

Requests
The only way an activity can affect the game-world is by issuing a request to an agent. Request statements ask agents if they wouldn't mind performing actions, and waits to find out if they actually bother to perform these activities.

A requests statement will appear in a state of the form:

     // needs conditions
     requests
          agent1.action1 !Þ Rejection(1)
          ®
          Finished
     {
          // actions to perform while waiting
     }


The first time this state is entered, the requests are passed to the agents concerned. From then on, we wait to see if any agent rejects the request; if so the rejection message is passed. If all agents finish their requested activities, state moves to Finished.

Messages
Messages are a way for activities to communicate without having to knowing each other's implementation details. Activities respond to messages using message-handlers. A message can have various parameters which are passed to the handler. If a message is passed to an activity, the handler function is called immediately. The handler may or may not change the state of the activity. Messages can be defined at any level of the state hierarchy -- handlers lower down the chain take priority over more general handlers.

______________________________________________________
Example Activity


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service