Why Use MVC for Games? A Q&A Session

  • strict warning: Non-static method view::load() should not be called statically in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/views.module on line 843.
  • strict warning: Declaration of views_plugin_display::options_validate() should be compatible with views_plugin::options_validate(&$form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/plugins/views_plugin_display.inc on line 1877.
  • strict warning: Declaration of views_plugin_display_page::options_submit() should be compatible with views_plugin_display::options_submit(&$form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/plugins/views_plugin_display_page.inc on line 481.
  • strict warning: Declaration of views_plugin_display_block::options_submit() should be compatible with views_plugin_display::options_submit(&$form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/plugins/views_plugin_display_block.inc on line 193.
  • strict warning: Declaration of views_handler_field_broken::ui_name() should be compatible with views_handler::ui_name($short = false) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_field.inc on line 641.
  • strict warning: Declaration of views_handler_argument::init() should be compatible with views_handler::init(&$view, $options) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_argument.inc on line 745.
  • strict warning: Declaration of views_handler_argument_broken::ui_name() should be compatible with views_handler::ui_name($short = false) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_argument.inc on line 770.
  • strict warning: Declaration of views_handler_sort_broken::ui_name() should be compatible with views_handler::ui_name($short = false) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_sort.inc on line 82.
  • strict warning: Declaration of views_handler_filter::options_validate() should be compatible with views_handler::options_validate($form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_filter.inc on line 585.
  • strict warning: Declaration of views_handler_filter::options_submit() should be compatible with views_handler::options_submit($form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_filter.inc on line 585.
  • strict warning: Declaration of views_handler_filter_broken::ui_name() should be compatible with views_handler::ui_name($short = false) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_filter.inc on line 609.
  • strict warning: Declaration of views_handler_filter_boolean_operator::value_validate() should be compatible with views_handler_filter::value_validate($form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc on line 128.
  • strict warning: Declaration of views_plugin_row::options_validate() should be compatible with views_plugin::options_validate(&$form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/plugins/views_plugin_row.inc on line 135.
  • strict warning: Declaration of views_plugin_row::options_submit() should be compatible with views_plugin::options_submit(&$form, &$form_state) in /usr/www/users/smasher/deadpanic_drupal/sites/all/modules/views/plugins/views_plugin_row.inc on line 135.

Q: Why should I use the Model-View-Controller pattern when writing games?

A: I'm glad you asked. I'll leave a general explanation of Model-View-Controller to Wikipedia, and just concentrate on how it benefits your game project. MVC makes your game easier to write, easier to understand, and easier to update in the future.

Q: Design patterns are just a bunch of fanboy wankery. Besides, it sounds very enterprise-y and I'm all kinds of agile!

A: That's not really a question, is it? But no, they're not wankery, or a fad, or an excuse to show how clever you are; they're solutions to real problems. If a pattern doesn't seem useful to you  then it's possible you've never encountered the problem (yet) or the problem doesn't occur in your application. That's fine. But MVC can help you write clearer code, more maintainable code, and *less* code -- all good things we'll agree.

This doesn't excuse design pattern fanboys who turn every object into a singleton because they heard somewhere that patterns are good practice. That's true wankery.

Q: So what problem does MVC solve? For games, specifically?

A: MVC makes your code more flexible, and more able to withstand the slings and arrows of future changes. Do you dread the day a manager announces your game is changing from 2D isometric to 3D? Or 3D to a text adventure? Happens a lot - Zork was originally a first-preson shooter, true story. Or, even more commonly, you have to switch from UIViews to Cocos2D sprites (or Cocos2D sprites to tuned OpenGL) for performance reasons? With MVC you can replace the old "view" object  with a new one, and make *zero* changes in the model. I mean not even importing a new header file. That's good magic, right?

It's a not all sunshine and roses; you'll have to be conscious of the units you use in your variables (in the physics 101 sense, not the Starcraft sense.) If positions in your model are expressed in pixels, and speeds are in pixels per frame, then your model knows too much about the view. If positions are expressed in "map squares" or "percentage of screen" and speeds are in distance per second then you're already on the right track.

Once you've done that you could easily have two alternate rendering pipelines (OpenGL 1.1 vs 2.0 anyone?) and switch between them at runtime with one line of code. You could create separate views for separate screen sizes (iPhone and iPad anyone?) or at the very least confine the screen-size code to a single class.

Q: So MyMonsterClass shouldn't inherit from UIImageView or CCSprite? Why separate the model from the view?

A: Right, it should not. This is actually a point of confusion for noobs, since the word "model" can mean "3d model" or "data model." In the case of MVC, the M is your data model, or your game state. The game state should be its own class that inherits from the default object (that's NSObject in Cocoa.) It may contain lists of other objects, like lists of players and lists of monsters / obstacles. Those lists contain instances of other classes like MyCharacter and MyObject that inherit from NSObject and have properties for x, y, damage, hitpoints, etc.

Q: I'm never changing view classes, so I'd get no benefit from MVC.

You seem very sure about that! Still, there are other benefits.The "views" we've discussed so far are strictly visual, but a "view" could be any class that needs event info from the game state. How about a soundObserver class to observe changes and play the appropriate sounds? How about a networkPlayer class that communicates model changes to a remote player? With MVC It's easy to add new observers (views) without making changes to the model.

In addition to adding or changing views, separating the model is key when it's time to save and load your game. If all of the important gameplay information is in the game state object then you can archive it to disk and restore it with a few lines of code, and then recreate the view from the model.

Q: How do I know I'm doing MVC right?

A: Another good question, actually. Just because you have a view class and a model class and a controller class doesn't mean that you've done MVC right. Notice the dotted lines in the diagram -- if you're not using the observer pattern to get messages from the model to the views then you're not getting your money's worth. Does your model import the headers from your view classes? You shouldn't. Can you add new views without making any code changes to the model? You should be able, otherwise that doesn't sound like MVC.

If you're not getting the benefits of MVC then you may not be implementing it correctly. You'll know your doing it right when your job gets easier! When you understand MVC it should hit you like a lightning bolt -- your code gets both simpler and more flexible and you start getting home from work earlier and earlier. That's success right there.

Q: How can I implement MVC in Cocoa?

A: Now I'm really glad you asked. In my last post I explained a lightweight way for your views to observe your models, and in my next post I'll give some example code for writing a MVC game in Cocoa.