MVC pattern

Comming from a business software background, I’ve been using the model-view-controller pattern alot. I am doing a little hobby project diablo style game wannabee and started out designing the model and the view seperately. This allowed me to not worry about collisions but also means that the scenegraph (the view) and the model must both be updated.

I was just wondering about how others are architecting their software?

I also read an article on slashdot last week by a “professional” game developer i the industry and it seemed like they dont architect their code at all and only has focus on 3D speed and effects.

My thoughts are that if I wanted to build a robust game engine I should build one that i very loosely coupled…

any comments anyone?

Michael

I pretty much stick to Model/View split. It helps when writing server/client interactions. In addition helps when you want to do a 2D, Isometric and 3D version of your game… :slight_smile:

Kev

Hi Kev

Just my thoughts. By seperating the model and view I can always upgrade the look and feel later when I get better at 3D while still having fun playing my game.

Michael

Out of my apparent cluebieness, would you mind giving me a short example of your MVC modeling in the game??

I am actually aware of the MVC patern, which I find it very interesting and am trying to follow it to my best. However I am still curious of how others envision its use in a game.

Thanks, and forgive my newbiness… :stuck_out_tongue:

Say you’re writing a space game, you know Elite style in space, you’re entities are maybe:

Ship.java
SpaceStation.java
Planet.java

Each of these entities will have data about them, their position, orientation and velocity maybe. In these classes you store these are pure data.

Then in your rendering layer you might implement:

Ship3D.java
SpaceStation3D.java
Planet3D.java

Each of these knows how to render the appropriate 3d geometry for the assocaited data object. Each object holds a reference to a data element. They are responsible for adjust the geometry as the data objects change.

Note however the data objects are responsible for detecting collisions and such. So the “View” is dependant on the “Model” but not vice vesa.

So now, say you come to write a server for multiplayer version of your space game. You can run the data model on the server, sync it via the network with the data model on the client. The View doesn’t know anything about this it just continues to work as tho the data model is fine.

Now you’ve got your 3D networked version working but you now want to implement a 2D version. You implement a new View which is dependant on the data model and everything else gets reused (the collision, the data model, the network code).

Kev

In my approach, I actually use a more strict separation of Model and controller, in addition to View. Model is pure data, plain and simple. Controller objects load the model with data (from database or file or network or wherever) and also save it when needed. View objects are responsible for rendering the Model objects (in 2D, 3D, 2.5D, HTML, or whatever).

Also, for a particular GUI platform (2D vs 3D vs cellphone for example), there are platform-controllers that handle input for the GUI and feed it to the rendered View. So, for example, keyboard input, mouse input, joystick input, phone buttons, network messages, etc. all feed the View, and the View doesn’t care where the input comes from.

I must admit, this creates a lot more classes in your object tree, and is arguably more work, but it adds flexibility to the design, and (for us) will make it much easier to support multiple platforms for our MMP game.

As a side note, having worked as a commercial game developer, I think the advantages of approaching a game architecture this way will start to outweigh the benefits of tweaking the rendering. As graphics hardware continues to improve, the ability to get an extra frame or two per second, or the ability to get an extra hundred (or thousand) polygons rendered will be irrelevant, and the ability to build reusable architectures to reduce development time and cost will become more important, along with better story and more interesting gameplay.

I’m trying to follow the MVC pattern, but I’m not sure if I am in the correct way…

I have, say, an IsometricMap, divided in two classes: IsometricMapModel and IsometricMapView. A map is composed by MapCells, that are also separated in model and view classes, and each map cells contains Tiles (also with model and view).

My question is: Am I just complicating things or is this the way to go? ???

My first cent - never forget that the purpose of all these software design patterns is to make life easier for the people actually writing and maintaining the code. They aren’t for performance, or for software correctness, etc. If you’re working on a solo project, use the patterns in whatever way makes the most sense to you.

Second cent - I’ve been using a pattern like this lately, which is MVC-derived and pretty useful. I have four types of classes - Game Objects (Model), Renderers (View), Managers (Controller - pt 1), and Controllers (Controller - pt 2).

Game Objects for the most part are just data structures. I usually have one class of these per entity in my world - in my case characters, towns, dungeons, etc. Getters and setters abound

I typically have one renderer for each ‘screen’ - so one for the menu, one for drawing the ‘in town’ display, one for drawing the ‘world map’, etc. Renderers just takes a list of relevant game objects and draws them to the screen. They have logic, but it’s all focused on rendering - culling, etc. Right now I just have renderers running in their own thread, but you could synchronize them with the game loop. Renderers may have data structures that parallel Game Objects (such as vertex data), but I try not to put that data into the Game Objects themselves.

Managers conceptually should contain all the game logic. Lately I’ve been orienting these around game states - which correspond to screens - same as renderers. There is one master manager that keeps track of game state and calls an update method on any active ‘children’ managers.

What I call ‘Controllers’ are assigned to any autonomous entities in the game world, and are responsible for choosing actions for the entity they represent. So the player’s Game Object, and any monsters or NPC’s are each assigned a Controller. Controllers are responsible for querying the world around their assigned entity, formulating a good action, and returning that to whichever Manager class is asking for an action. Controllers have no ability to update the world - they just return instructions to a manager class such as ‘Walk North’ or ‘Open Door’. The manager class is responsible for checking the validity of this instruction and actually moving the game object or opening the door.

There is one special controller for the player that basically maps keyboard and mouse events to instructions in the controller ‘instruction set’, which may be returned to a manager class. If you’re making a turn based game, you have the player controller stall until the user enters an action. If you’re making a real time game, you have the player controller just return NOOP if the player isn’t pressing a button or whatever.

So the basic idea is that you have all these Game Objects that represent the things in your world. Alone these objects don’t do anything. You add on top renderers that show a list of game objects. The list of game objects they display may be limited by a manager class (to eliminate nearby but hidden enemies for example). You add on top of this a layer of manager classes which are responsible for updating the game state (Game Objects). Finally, controllers are responsible for suggesting to the manager classes how to update the game world.

Anyway, that’s the architecture I’ve been using lately. I’ve found this model very flexible and easy to extend. Let’s say I want to add gravity to my world - that belongs in the manager class ONLY. I may choose to enhance a controller class to compensate for gravity, but that’s an independant chunk of work. Let’s say I want to improve pathfinding - I add that to a controller class. If I want to switch to a different rendering engine, I swap out the renderer class for the relevant game state(s). If I want to make the game network enabled, I just create a new proxy controller class which communicates across to some client over the network (which is of course not at all a trivial task).

[quote]never forget that the purpose of all these software design patterns is to make life easier for the people actually writing and maintaining the code. They aren’t for performance, or for software correctness, etc. If you’re working on a solo project, use the patterns in whatever way makes the most sense to you.
[/quote]
Yep, that what I’m aiming at: to make the code easy to maintain (I what it to be easy to add / modify features). I’m just not sure I’m on the right way.

Your architecture is very interesting (somewhat similar to mine, but a little more complex and complete). But it might get difficult for new developers to understand it - unless it is documented. How do you do it?
???

In my case, I’m the only developer, so no communication problem. In general, I find that if you can establish one sensible, robust pattern, and then use that over and over again, your system will be pretty easy to get around for new coders - once they understand the major pattern you’re using.

Javadoc is your friend. If you use JBuilder or Eclipse, they can automatically start the Javadoc comments for you. Then you can fill in the details. Also, writing a quick 1 or 2 lines about a method or class will make you think about what you are doing, so you have a better chance of doing it right the first time. If you do it while you are coding, you will get into the habit. If you wait until the end, you will never do it.

…but not a subsitute for documentation. Javadoc is only a reference manual, not a developer-guide. If you are going to “customize” or ignore patterns, you need developer-guide levels of explanation if other people are to be able to work with it.

[quote]…but not a subsitute for documentation. Javadoc is only a reference manual, not a developer-guide. If you are going to “customize” or ignore patterns, you need developer-guide levels of explanation if other people are to be able to work with it.
[/quote]
That’s exactly the point. I’m not concerned with Javadoc, they are easy to do and I’m already doing it with no problems. What I’m thinking about is a higher level of documentation, the one that can help you understand the game architecture without having to read the source of a 100 classes.

In doing my own coding, I also find patterns to be extremely useful.

I’m currently using an MVC-based pattern for most of my current project. What I find most useful is this:
You know how you work on something, say a map editor for your game, and you fight with it to get it to work, the UI code is driving you mad (or some other bit). You try several different approaches, nothing works quite right, and after 2 solid weeks of work and tweaking you’ve mutilated your code beyond recognition.

Well, patterns usually help me avoid this sort of problem in the first place, but when you’re navigating uncharted territory (i.e., learning something new in the Java API), and because you’re learning you’ve totally written it wrong on your first attempt. Well, the MVC pattern in particular allows me to trash entire sections of code and start over without any serious impact on the rest of my code. That feature of patterns alone is well worth the use of patterns, I believe.

Writing games with performance in mind as your #1 priority is fine if you’re writing something that needs to squeeze every ounce of performance out of the computer it’s running on. But even then it’s a bad idea. The time in building your code properly, as you’ve probably learned in business software, is well worth the effort.

In my opinion, one of the main reasons that game programmers (traditionally?) don’t write well-built code comes from a number of reasons:

  1. Much of the code cannot or will not be used on future projects (which really shouldn’t be the case)
  2. Unfortunately, at least in the PC realm, people are used to downloading patches to make games work, so the quality control isn’t there, and to put it there might cost way too much money and time.
  3. Typically, people are more tolerant of flaws in video games than they are in their operating system, word processing, or database software. Businesses simply don’t want to tolerate a “beta” program when it’s their costomer’s data and their reputation on the line (which also shouldn’t be the case in the games industry - but hell, it is).
  4. The average customer in the games industry invests $50 or less in your video game - if it’s got bugs they can deal with being out $50, or having to wait a week for a patch. Businesses that invest thousands of millions of dollars in a software sollution for their business have enough personnel and training issues to resolve - they don’t want to have to fight their software as well.

My point is, building robust software is the gold standard no matter what the application. Readability and maintainability ought to be the #1 concern in coding, in my opinion.

well I want to add my experience ;D
I’ve been breaking my head about what are models/controllers and views.

Model: Data, with simple actions does not interact with the surroundings
View: Renders the model, by events or by polling
They are both self contained, view does not change the model, model does not change the view.

Then comes the controller, which seems to get a different description each time i read about them.

[quote] Controllers are responsible for querying the world around their assigned entity, formulating a good action, and returning that to whichever Manager class is asking for an action. Controllers have no ability to update the world - they just return instructions to a manager class such as ‘Walk North’ or ‘Open Door’. The manager class is responsible for checking the validity of this instruction and actually moving the game object or opening the door.
[/quote]
I still don’t get it. Maybe that’s because I add functions to the game objects with validation instead of gameobjects that are just data with getter and setters. Could somebody explain the controller again :-\ from the click from the user to the unit moving. Maybe then I can kick it into my head.

So Rule#1 a Unit can only attack if it has not been destroyed.

unitManager.attack(Unit attack, Unit defender) {
if !attacker.isDestroyed()
  attacker.attack(defender)
}

I did it a bit differently, I added an attack function to the unit and then where the rule should be checked I ask a rules object if the attack can be done.
ie. unit attack code:

attack(Unit attack, Unit defender) {
if rules.canAttack(attacker,defender)
attack(defender)
}

comes down to the same thing…

I have another question:
If a unit dies a dying animation is shown which ends after x ms. after that the unit should be garbage collected. This is the only time that I have the gui remove the unit from the model.

ie

unit.die() {
setState(DYING)
}

unitSprite {
if state == DYING
anim = animDying

if dyingAnim has elapsed remove unit from model
unit.destroy -> will remove the unit from the model, but is called from the gui!
}

how can I avoid that?

http://www.freewebs.com/cortlesteeze/pix/ThreadNecro.jpg

(should the image not work in the future, thats ok just know that I can’t attach it as it probably violates copyright laws and stuff)

Reply #13 on: 2004-10-18, 10:41:36 :wink:

Where did he get that one black mana? :o

But it is such an informative thread ;D no srry, I’ll look at the date next time.