Systems Architecture Overview

A good way to explore Torque is to think of the engine as a series of integrated systems that work together to manage the mundane tasks of game development. As a game programmer, we want to avoid these low level details, but we need to understand how Torque deals with them, and learn how to correctly utlize the underlying systems, instead of fighting with them. Once you have a basic understanding of the primary systems and what they do, your development time with Torque will become much more effective and efficient.

Before we get into the key systems however, it's important to understand a fundamental aspect of Torque development: the platform layer.

Torque is designed from the ground up to allow developers to make their game abstracted completely away from the underlying hardware, so that once completed the project can be deployed to any platform that has an implementation for the hardware specific systems (see below). This is a huge benefit for game developers, allowing you to work on your project without focusing on (or even being aware of!) platform specific requirements or restrictions, other than how they would affect game play itself.

With careful understanding of how to work above the platform layer, projects developed with Torque can be easily ported to other operating systems and platforms.

Note:
The following discussion is general in nature. Users should be aware that the Torque Game Engine Advanced 1.7 license currently supports Windows XP and Windows Vista systems only. There is a separate license available for the Microsoft X-Box 360, for further information regarding this license contact licensing@garagegames.com. The engine infrastructure is designed to allow for adaptation to other platforms, and other platforms and licenses may be supported in the future.

Core Torque Systems

Torque has dozens of systems and managers that you will eventually interact with, but for the most part you will be dealing with just a few extensively. Listed below are the systems you will be working with the most, including a brief description of their key tasks and responsibilities.

The Console

The Console is the lowest level system within the Torque Engine, and is responsible for:

  • Object Instantiation via TorqueScript
  • Remote and Cross Platform Object Instantion via the networking layer
  • TorqueScript interface to the Simulation
    • TorqueScript Methods and Functions
    • Console (C++) Methods and Functions
    • dynamic and persistent fields

While we work with the Console system every single day, most of what it does is automatic, and we do not do anything explicit to use the system. It is important however to understand what it does so that when you are implementing a new object in C++, you are aware of the requirements to work within the system.

The Simulation

The Simulation is where objects are maintained, and can be considered a big container where all of our objects live. It provides some powerful functionality, including:

  • Object Registration
    • Unique Identification Numbers -- every object in the simulation can be identified via id number or (optionally provided) name
    • Smart Referencing -- when an object is de-registered from the simulation, it will notify other objects that it is being removed
  • interface with the Console and other systems
  • built in editor interfacing

The key benefits of the Simulation system are that we can search for, and reference objects by unique identifiers, which then allows us to call methods, modify data, and otherwise manipulate those objects. In addition, with proper use of smart referencing in C++ development, we can avoid most if not all situations where pointers can become corrupt and crash our executable.

The Network Connection

The Network Connection system manages all of our client/server communications, and provides the ability for communications across the Internet and other networked environments. Torque utilizes UDP as the basis of the networking system, and implements a wide variety of capabilities on top of standard UDP:

  • Object Synchronization
    • Remote/Cross Platform Instantiation -- leveraging the Console system, Torque servers can direct clients to remotely instantiate Torque objects
    • Streaming Updates -- otherwise known as the Ghosting System, Torque can stream optimized updates to clients
    • Client specific scoping -- Clients are only sent information about objects they are near, providing anti-hack and anti-cheat benefits, as well as network optimization
  • Networked Events -- Torque provides for a variety of event types and deliveries, including:
    • Guaranteed Ordered
    • Guaranteed
    • Unguaranteed
  • Mission loading and synchronization

The networking system within Torque is very complex, and will take time to learn to use effectively. Fortunately, for most uses the system automatically takes care of everything you need, so you don't have to!

GFX: Abstracted Rendering for modern video hardware

New with Torque Game Engine Advanced, the GFX system is a fully hardware abstracted rendering system designed to completely isolate the developer from the underlying hardware requirements. GFX is specifically engineered to leverage the power of Graphics Processing Units on your video hardware, and utilizes many features to optimize rendering:

  • Batch Management -- rendering requirements are delivered to the hardware via batches to best leverage hardware design
  • Materials -- flexible descriptions of textures and shader effects, including optional fallbacks for older hardware, including non-shader capable video cards
    • Basic -- procedurally generated shaders based on TorqueScript defined properties
    • Custom -- TorqueScript defined properties tied to HLSL compliant shader implementations
  • Render Devices -- hardware specific implementations for the abstraction system
    • DX8
    • DX9
    • NULL (for dedicated servers)
    • XB360 (licensed separately)
  • Texture Management -- Torque seamlessly manages textures by leveraging the Resource Manager system, only keeping the minimum amount of information necessary to maintain desired texture quality

The GFX system is fully user expandable for a variety of hardware requirements (additional license may be required, see the EULA).

SFX: Abstracted sound management

TGE-A 1.7 for the first time provides an abstraction layer for game sound, and mirrors the GFX system in utilization. Game Developers implement against the SFX abstraction layer, and SFX takes care of the hardware details by utilizing any available SFX Devices. TGE-A provides the following SFX devices out of the box:

  • DirectSound
  • FMOD (additional 3rd party license required)

Resource Management

Torque maintains reference count based information of all resources loaded into memory, and therefore minimized memory used by only keeping one copy of a resource available at any time. When your project requires access to the information contained within a resource, a reference to the already loaded information is returned instead. The Resource Manager allows developers to define any type of resource, and tracks many resources by default, including:

  • Models
  • Animations
  • Sound

Game Processing

Game processing occurs at a fixed frequency of 32 milliseconds by stepping through the process list (a linked list of objects that derive from the GameBase class and have registered with the Simulation) one by one, and calling the method ::processTick() on each object.

Within this method, each object is responsible for updating itself in response to the passage of time, as well as reacting to any Move inputs that may have been delivered from the client for that object. Only one Move struct is delivered from the client, and only for one particular object, known as the control object.

During the processTick() call, simply objects may do very little--possibly just rotating slowly in place such as how the Item class operates, while complex objects such as the Player may perform many tasks.

A complex game object however has quite a bit of responsibility, and may be responsible for:

  • Physics
  • Collision
  • State tracking (dead/enabled/disabled)
  • Procedural animation selection and control
  • Move input processing (control object only)
  • Sim synchronization calculations
  • Network synchronization and data streaming notifications
  • Synchronization actions such as extrapolation and client side prediction

In addition to ::processTick(), client side objects receive update calls as listed above for both interpolation requirements (::interpolateTick()), as well as animation and other variable rate time update needs (advanceTime()).

Client simulations are also responsible for staying synchronized with the data sent by the server, and in the case where the client simulation differs from the server's data, the client will correct any objects that are not synchronized back towards the state that the server dictates. Occasionally, if the client is very de-synchronized, they will "warp" objects back directly to the server's directed state, but only in situations where the de-synchronization is beyond acceptable limits.

Networked Updates

Due to the nature of a networked environment, two simulations can never be exactly synchronized--since it takes time (known as latency) for data to travel from the server to the client, by definition the client is always "behind" the server. This sets up a situation where it makes sense for us to allow the client to manage it's own simulation, but correct towards the server's "true" state during it's Game Processing phase for each object.

For this to work well, the server is responsible for tracking data that has changed on every object in it's simulation, and when appropriate, deliver this data to each client so they can proceed with updating their simulation towards the authoritative server state.

The system that manages this complex interaction is known as the Ghosting System, and it is tightly coupled to both Game Processing and the Network Connection.

During a server's Game Processing loop, each object that has it's world properties (position, velocity, game state, or any user defined values that must be networked to the client) modified "marks" the data as being dirty by using a method provided by the NetObject class called setMaskBits().

In parallel with the Game Processing loop, there is a Net Update processing loop that tracks every object that each client knows about, and when any object within a client's list is marked as "dirty", it packs a network update to be delivered to the client for that object. Once it has iterated over all objects the client is aware of, it delivers this update to the client.

When the client receives a ghost update from the server for a particular object, it updates the information (knows as a delta), and then begins to correct back to the state the server has directed, giving us smooth corrections that are normally not noticeable by the player in any way.