This file describes the simulation- and network-API of UltimateStunts. As
UltimateStunts is still under construction, the information in this file does
not describe the final design. This file does not describe other UltimateStunts
API's, like the file-transfer API, the graphics API or the sound API.
This file was last updated on September 11 2003, by CJP.
A session in which one or more players are playing the game. This can for
example start when a number of players have connected to each other, and stop
when all players have either crashed or finished.
A program in the network stucture, connected to one or more client programs. The
server program is the "leader" of the game-session it is involved in. It is able
to start and to stop the game session. The server distributes data between
clients, and acts as a central point for simulations. The server is able to
provide zero or more players for the game session.
A program in the network structure, connected to a server program. The client
program accepts the server as the "leader" of the game session. It is able to
provide one or more players for the game session.
A program not connected to any other program via network connections. The
stand-alone program is the "leader" of its own game-session, and all players
participating in that game-session are provided by the stand-alone program.
A person or a program-section participating in a game session. Every player
controls one moving object: the output of the player influences the behaviour of
the moving object.
A player who's behaviour is controlled by the program being discussed. This is
totally equivalent to saying that this player is provided by the program being
A player who's behaviour is controlled by another program than the one being
discussed. Remote players only exist in networked game sessions, so they don't
exist in a standalone program. Every non-local player is a remote player.
A player who's behaviour is controlled by user-input. If the program, to which
the user-input is being sent, is being discussed, then the human player would be
called a local player.
A player who's behaviour is controlled by a computer algoritm. If the program,
in which the algoritm is located, is being discussed, then the AI player would
be called a local player.
An object that is a part of the physical model of the game.
Information necessary to describe the state of a (physical) object. Examples
are: position, velocity and engine RPM of a car. Properties that remain
constant during the game, like the speed of a windmill or the mass of a car,
are not parameters; these are predictable, and are not necessary for describing
the state of the object.
A type of (physical) object that has zero parameters, so that its behaviour
can be predicted from the beginning of the game. Tiles are examples of static
A type of (physical) object that has one or more parameters. Dynamic objects
can be influenced by physical events. Cars are examples of dynamic objects.
A type of physical object, that has at least the position, velocity,
orientation and angular velocity as its parameters. By definition, all moving
objects are dynamic objects. Cars are examples of moving objects.
A set of objects, both static and dynamic, defining the environment of the
game session. All physical objects involved in the game session are parts of
A simulation modifies the state of the moving objects in the world, in
accordance to the input from the players. For example, there are simulations
that implement physical laws, or that check the rules of the game. There are
also simulations that synchronise the world data in all programs in a networked
game session. A program can use more than one simulation at the same time.
CBinBuffer : public vector<Uint8>
CBinBuffer is our standard binary container class.
- operator+=(const type); //for various types
- gettype(); //for various types
CMessageBuffer : public CBinBuffer
CMessageBuffer is an advanced CBinBuffer, special for CMessages. It contains
a header and message-specific data. header+data is called buffer.
- CMessageBuffer::eMessageType getType();
//e.g. car input, car parameters, or cow input :-)
- bool setType(const CMessageBuffer::eMessageType);
- CBinBuffer & getData() const;
- bool setData(CBinBuffer &);
- CBinBuffer & getBuffer();
- bool setBuffer(const CBinBuffer &);
CMessage is a base-class for all kinds of messages: e.g. input data from a
player to its moving object, or dynamic object parameter data. Data can be
converted to a binary representation using the getBuffer method.
Derived classes might want to overload getBuffer and setBuffer in order to
adapt the behaviour of the object. They probably also overload the getType
- CMessageBuffer getBuffer();
- bool setBuffer(const CMessageBuffer &);
- eMessageType getType() const;
An ObjectChoice message is used to describe what kind of moving object
is desired by a player. This includes the kind of object (car, train,
cow etc.), the type (e.g. the car model) and additional settings.
- eMessageType m_ObjType;
- CString m_Filename;
CMovObjInput : CMessage
Input data coming from a player and going to a moving object. Input data is
handled in a general way using the four float properties.
- float m_Up, m_Forward, m_Backward, m_Right;
CCarInput : CMovObjInput
Input data coming from a player and going to a CCar object. Derived from
CMovObjInput. Steering data is sent via m_Right, gas data via m_Forward,
brake data via m_Backward and m_Up is not used.
- Uint8 m_Gear;
- bool m_CarHorn;
CMaterial provides material-properties, like the static & dynamic friction
coefficients. It also contains data for other subsytems of the game, like the
location of a corresponding texture file.
- bool loadFromFile(CString filename, int mul);
- CString getFilename();
- int getTextureMul();
CShape provides a vertex-based collision model. It also contains data for other
subsytems of the game, like the location of the geometry file.
- bool loadFromFile(CString filename, CString subset);
- CString getFilename();
- CString getSubset();
CBound provides a plane-based collision model. It also contains data for other
subsytems of the game, like the location of the geometry file.
- bool loadFromFile(CString filename);
- CString getFilename();
CTile is the elementary data type of which a track is built. The track
actually is an array of this type. The place in the array, together with
the m_Z property define the position of the tile, while the m_R property
defines the orientation. The m_Shape property is an index of an element of the
A part of a physical object. The bodies of a physical object are rigid bodies,
and they can move relative to each other. The m_Position and m_Orientation
properties define the position and orientation of the body, and the m_Body
property is the index of an element of the bound-array.
- int m_Body;
- CVector m_Position;
- CMatrix m_Orientation;
CDynamicObject : public CMessage
Implementation of a dynamic object. It is derived from CMessage, so that its
parameters can be get/set via the get/setBuffer methods. Input data of this
object can be reached via m_InputData. Players/network interfaces can set this,
and simulations/network interfaces can read it. The constructor of the derived
classes should create a m_InputData of the right type.
As this class is used for physical objects, m_Bodies and m_Sounds have been
- CMessage *m_InputData;
- bool hasChanged();
- vector<CBody> m_Bodies;
- vector<int> m_Sounds;
CMovingObject : public CDynamicObject
Implementation of the moving object as described in the definitions.
Various methods provide a vector-based version of the position-data.
Derived classes may have additional parameters. If so, they have to
provide their own getBuffer and setBuffer overload methods.
By default, CMovingObject uses a m_InputData of the type CMovObjInput.
The simulate method simulates the type-dependent physics of the moving object.
- void simulate(CPhysics &)
//Gets+sets for position parameters
- CVector getPosition();
- void setPosition(CVector);
- CVector getVelocity();
- void setVelocity(CVector);
- CVector getOrientation();
- void setOrientation(CVector);
- CVector getAngularVelocity();
- void setAngularVelocity(CVector);
- const CMatrix &getRotationMatrix();
- void setRotationMatrix(CMatrix &m);
//Additional get for approximation model
- CVector getAcceleration();
CCar : public CMovingObject
CCar is a class derived from CMovingObject. The m_InputData member
is of the type CCarInput.
- CVector m_FrontWheelNeutral, m_BackWheelNeutral;
- float m_WheelRadius;
- float m_WheelVelocity, m_WheelAngle;
- float m_WheelHeight1, ...;
Implementation of the "world" as described in the definitions.
- bool loadTrack(CString filename);
- void unloadTrack();
- vector<CTile> m_Track;
- int m_L, m_W, m_H;
- bool loadMovObjs(CString filename);
- void unloadMovObjs();
- vector<CMovingObject *> m_MovObjs;
- vector<CShape *> m_TileShapes;
- vector<CBound *> m_MovObjBounds;
- vector<CMaterial *> m_TileMaterials;
- vector<CMaterial *> m_MovObjMaterials;
- vector<CString> m_MovObjSounds;
- CString getBackgroundFilename();
- ...(other objects, like a chat radio)
Base-class for all players. On initialisation, the world object should be
given to the player. When the object is registered by a CPlayerControl-object,
the m_MovingObjectId and m_PlayerId should be set.
When update() is called, the player-object is allowed to think about its
intelligent response, and it writes its actions to the m_InputData of its
- CPlayer(const CWorld *w);
- bool update(); //Returns true if input data has changed
- int m_MovingObjectId; //Index of moving object being controlled
- int m_PlayerId; //Index of player. Set by CSimulation.
CAIPlayerCar : public CPlayer
Implementation of a local AI player, specialised in controlling cars.
CClientNet : public CFileCtrl
CClientNet is the client-side implementation of the network protocol. It is
derived from CFileCtrl, so that it can manage file downloads.
- CClientNet(CString host, int port);
- bool connect(); //returns true on succes
- bool hasSlowConectionType();
//needed to decide if approximation or physics should be created
CServerNet is the server-side implementation of the network protocol.
- bool startListening(int port, int max_new_clients);
- void setClientPolicy(int max_new_clients);
Base-class for all simulations. A CSimulation-object should be used as follows:
- Create a CWorld object
- Construct the CSimulation, using the CWorld object
- Load the track into the CWorld-object
- Add players to the game
- During the game, call update() frequently
- CSimulation(CWorld *);
- bool update(); //returns false if game has stopped
CPhysics : public CSimulation
CSimulation-class doing the "real" physics calculations.
CApproximation : public CSimulation
CSimulation-class approximating physics with some fast calculations.
CClientSim : public CSimulation
CSimulation-class to be used in client-programs. Connects to the server program
and synchronises the world-data frequently. CClientSim does not simulate
any physics, but it can be used together with CPhysics or CApproximation. To
choose between them, use the CClientNet::hasSlowConectionType() method.
- CClientSim(CClientNet *, CWorld *);
- CString getTrackName();
CRuleControl : public CSimulation
CRuleControl checks if players are following the right route, gives them
penalty time, checks if theyre finished, etc. This simulation can be used
together with CPhysics in a server program or in a local game.
CPlayerControl is used to manage the players in a game session. With the
addPlayer method, an integer is returned, which can be put in the m_PlayerId
property of a CPlayer object. A negative value means that the adding was not
succesful, for example, because it was refused by the server. After all local
players have been added with addPlayer, the loadObjects method should be called.
This will load the moving objects of all players into the world object.
The default implementation is suitable for local games.
- CPlayerControl(CWorld *w);
- int addPlayer(CObjectChoice);
- bool loadObjects();
CClientPlayerControl : CPlayerControl
An implementation of CPlayerControl based on communication with a server, for
use on the client-side of non-local game sessions.
- CClientPlayerControl(CClientNet *, CWorld *w);
The UltimateStunts main program ("ultimatestunts")
The main program can act both as a client and as a standalone program.
The only difference between these is that in the first case a "CClientSim"
object is used together with a "CPhysics" or a "CApproximation" object, and in
the second case a "CRuleControl" object is used together with "CPhysics".
This program creates at least one CHumanPlayer instance, and is able to create
The UltimateStunts server program ("stuntsserver")
The server program always acts as a server, and it may also act as a client.
The simulation objects in the pure server mode are the same as in the
stand-alone mode of the main program. The configuration in client-mode is
identical to that of the main program in client-mode. This program is able to
add several AI players to the game.
Communication with clients is done by a CServerNet object, possibly by using an
indirect way through CPlayer-derived objects.
The UltimateStunts AI client program ("stuntsai")
This is the most simple of the three programs. This program always uses one
CClientSim instance an either a CPhysics or a CApproximation instance, and like
the other programs, it is able to create several CAIPlayer-instances.