Changes between Version 8 and Version 9 of EngineDocumentation


Ignore:
Timestamp:
Feb 23, 2008, 10:10:25 AM (16 years ago)
Author:
Matei
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • EngineDocumentation

    v8 v9  
    1111The game logic code works the same way whether the game is multiplayer or single player - all that differs is how commands are treated. We'll first describe how the game logic code is organized before explaining the details of setting up multiplayer. The game logic is implemented in the simulation module, most notably in CSimulation, which handles all updates, and CEntity, which represents and updates an in-game object (unit, building, etc). In both multiplayer and single player, the game state is updated in ''turns'', which are about 150 milliseconds each. Each turn, objects move to some new position, units may gather resources or do damage (depending on their gather rates), etc. A turn is handled in the CSimulation::Update method. In addition, between turns, the graphical objects in the game are animated continuously as fast as the frame rate permits by interpolating between their previous turn's position and their next turn's position. This is done by CSimulation::Interpolate. There is a CTurnManager object which says when it is time for a new turn (the simulation queries this object each frame). While the game is running, commands from the player (obtained through the GUI) are queued up using CTurnManager::!QueueLocalCommand. Each turn, the turn manager provides a ''batch'' of commands to the simulation based on what was queued up. The only difference between single player and multiplayer is which turn manager is used: The multiplayer turn manager sends commands to the host, which buffers a batch of orders and then broadcasts them to all players, thus making sure that all clients get the same batches of commands, keeping their simulations in lockstep. The single player turn manager sends commands directly to the simulation. All commands are validated before being played, to prevent cheating. When AI is implemented, it will be done by simply sending orders from the AI player to the order queue as if a human player had issued them.
    1212
    13 Most of the game logic happens in CEntity and its related scripts (binaries/data/mods/official/entity_functions.js) and helper classes (like CEntityManager). All objects that a player may interact with in the game are ''entities'' - including units, buildings, trees, any obstacle that has an effect on pathfinding, etc. Each entity is represented in the game world by an ''actor'' - a graphical mesh with potentially some other meshes attached to it at ''prop points'' (things like shields, weapons, or the rider on a horse). There are also purely decorative objects that are not entities, such as grass blades or shrubs. These are implemented by having an actor with no entity. Actor drawing and animation is handled in the graphics package, including loading meshes and animations from 0 A.D.'s custom compressed formats, PMD (Pyrogenesis MoDel) and PSA (PyrogenesiS Animation).
     13Most of the game logic happens in CEntity and its related scripts (binaries/data/mods/official/entity_functions.js) and helper classes (like CEntityManager). All objects that a player may interact with in the game are ''entities'' - including units, buildings, trees, any obstacle that has an effect on pathfinding, etc. Each entity is represented in the game world by an ''actor'' - a graphical mesh with potentially some other meshes attached to it at ''prop points'' (things like shields, weapons, or the rider on a horse). There are also purely decorative objects that are not entities, such as grass blades or shrubs. These are implemented by having an actor with no entity. Actor drawing and animation is handled in the graphics package, including loading meshes and animations from 0 A.D.'s custom compressed formats, PMD (Pyrogenesis !MoDel) and PSA (PyrogenesiS Animation).
    1414
    1515Each entity has a hierarchical tree of ''properties'' as well as a number of ''event handlers'' implemented in !JavaScript. Entity types (such as different soldier types) are defined as XML "template" files in binaries/data/mods/official/entities. These XML templates can inherit from each other, so that, for example, all spearmen can inherit some properties from template_infantry_spearman.xml, but Celtic and Persian spearmen can be differentiated by modifying celt_infantry_spearman.xml and pers_infantry_spearman.xml. A property such as maximum health might be implemented in an XML file as <traits><health><max>100</max></health></traits> and will then be accessible through scripts and C++ code as traits.health.max. The XML files also define script functions that can handle various ''events'' for an entity. For example, an entity may choose to react when it's damaged by attacking the entity that damaged it. Most orders which require the entity to do some work are implemented as events. For example, if a unit has an attack with attack rate of 1 hit per 2 seconds, then as long as it is trying to attack a target, it will get a "handle generic order" event with action "attack" ever 2 seconds, and then a !JavaScript function will decide how much damage to inflict on the target and do so. The C++ code only does the "heavy-duty" work like pathfinding and collision detection, allowing most of the game logic to be handled in !JavaScript for a quick development cycle. One last thing to note about entities is that although they have many properties, only the properties that differ from those in the template, such as "current health", are maintained for each CEntity object. The rest are held by the template (CEntityTemplate). This means that it's possible to, for example, upgrade the attack of all current and future entities of some type by applying a change to their template. Entity properties and event handlers are described in detail at http://www.wildfiregames.com/users/code/wiki/index.php?title=XML.Entity. Scripting helper functions are implemented in the scripting module - Most notably, the CJSObject class, which makes it possible to expose C++ instance variables and methods in an object to !JavaScript fields and functions.