Wartbed:Architecture/MVC
From Dark Omen Wiki
WARTBED Architecture Architectural documents:
|
WARTBED |
Model-View-Controller ("MVC") is a software design architectural pattern and principle (sometimes also considered a design pattern) that defines how system components and responsibilities are separated and intended to interact. The main principle is the separation of system "logic" (rules or inner mechanics), user input (system-user interaction), and sensory representation (GUI, sounds, etc) from each other. The purpose if this is to loosen couplings and promote modularity. The WARTBED system architecture follows this design architecture.
Contents |
WARTBED's Model-View-Controller Design
Everything that can interact in a game world is a "game object" (or an "entity"). The WARTBED game objects exists in a virtual universe solely defined by its own logic and knows or cares nothing about their representation - they are pure Models. In principle, since all game logic takes place in the Model layer, a WARTBED game can run completely in the abstract without any graphical or auditory output at all. Every entity have one or more corresponding representations (views) that may read "their" entity but not change it. However, as is common in games software, the models CAN signal the outside world by sending messages.
In the conventional interpretation of MVC, the model and views are completely separated and only communicate through a controller. Sometimes, for reasons of efficiency, the view can observe the model. Though this observer pattern design is frowned upon or rejected by purists, it is common in computer game programming. | +------------+ +------------+ +------------+ | | | | | | | | | | | | | Model |<=== | Controller | ===>| View | | | | | | | | | | | | | +------------+ +------------+ +------------+ ^ | +--------------------------------------+ |
WARTBED assumes a pragmatic stance and though using a strict division of responsibilities between models, views and controllers, also accepts that architectural fundamentalism is not in the best interest of game development. The WARTBED MVC structure allows view objects to observe (though not change) model objects, and models can signal events by broadcasting messages to observers subscribing to it. Models still know nothing about the functionality of any subscribers, who are responsible for processing and responding to messages. | +-----------------------------------+ | Model | +--------------+---------------+----+ ^ ! The model can ! ^ | ! send messages ! | | ! ! | The controller | ! ! | The View can issues orders to | ! ! | read the Model model entities | V V | +--------------+----+ +-----+------------+ | Controller | -----> | View | +-------------------+ +------------------+ The controller can direct the view |
The controller module is essentially a game session. It ties together a set of participants (agents that wish to interact with the game world) with the models and views. | Models +---+ Players > | |-+ / +---+ |-+ +---+ +---------+ / +---+ | | |-+ <----- | | +---+ +---+ |-+ -----> | Session | +---+ | | | \ +---+ +---+ +---------+ \ | |-+ > +---+ |-+ * Humans +---+ | * AIs +---+ * Observers Controller Views |
Model and View
As example, assume a space game, where the main Model will be the class "Ship".
//---------------------------------------------------------------------------------------------------------- // Basic classes: f.i. in (made-up file) "MVC_base.h" //---------------------------------------------------------------------------------------------------------- typedef shared_ptr<Message> MESSAGE; typedef std::set<View *> VIEW_SET; | |
//----------------------------------------------------- // Model base class //----------------------------------------------------- struct Model { mutable VIEW_SET views; virtual ~Model() {} void registerView( View *pView ) const { views.insert( pView ); } }; | //----------------------------------------------------- // View base class //----------------------------------------------------- struct View { virtual void receiveMessage( MESSAGE &msg ) {} = 0; View( Model const &rModel ) { init(rModel); } virtual ~View() {} void init( Model const &rModel ) { rModel.registerView( this ); } }; |
//----------------------------------------------------- // Example model class, f.i. in "Ship.h" //----------------------------------------------------------- #include "MVC_base.h" struct Ship : Model { VECTOR3 position; // Example game long hull_points; // object data };
//----------------------------------------------------------- // Example view class, f.i. in "game_display.h" //----------------------------------------------------------- #incluide "Ship.h" struct ShipView : View { Ship const *pShip; OgreSceneNode *pNode; ShipView( Ship const *pShip ) : View(pShip), pShip(pShip) {} void receiveMessage( MESSAGE &msg ) {} void update() { pNode->setPosition( pShip->position ); } };
Example representations
View objects are similar to the Observer design pattern and hooks a model. Typical representations are
- The graphical model (3D model, each individual unit)
- An iconic representation (regimental banner, attached to formations rather than individuals)
- Audio (a helicopter constantly playing Ride of the Valkyries)
Controller
In real-time tactics games, no units are directly controlled by the player. Instead, all game objects are interacted with through orders. Therefore, the task of the Controller layer is to read input (from players, network or AI) and dispatch orders.
In WARTBED the Controller is two-fold. The server-side Controller is the Session class. A Session contains an universe of models and a set of subscribing actors. The client-side Controller subscribes to a server and contains a tableau of views representing a universe, about which it really knows nothing beyond what the server-side controller relays. The client-controller makes requests to the server-controller, which in turn interacts with the universe.
Views Actors ~ Server Models ~ session (universe) +---+ +---------+ ~ | |-+ <----- | | ~ +---+ |-+ -----> | Contr. | <--. +---+ | | | \ +---+ +---------+ ~ \ +---------+ +---+ ~ \ | | | |-+ ~ > | Contr. | -----> +---+ |-+ ~ / | | +---+ | +---+ +---------+ ~ / +---------+ +---+ | |-+ <----- | | / +---+ |-+ -----> | Contr. | <--ยด +---+ | | | ~ +---+ +---------+ ~ ~ ~ Application-side ~ Server-side