MVC understanding

Started by
19 comments, last by Kylotan 7 years, 7 months ago

There is no game world, there is no player character, and there is no spoon.


Oh. So this guy thinks he's the Oracle now....

Beginner in Game Development?  Read here. And read here.

 

Advertisement

nospoon.jpg

When you really get down to it, the amount of weirdness that happens between a photon hitting something and that information finally reaching your awareness is pretty freaky as well. The things we "see" are actually just an upside-down version of our own private ideas that we superimpose onto color and depth information coming from a stream of photons and translated through a lump of fat in a calcium bubble.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Ah. So if Skynet had a voxel raytracer....

Beginner in Game Development?  Read here. And read here.

 

okay, lets say I have another project, where I got some kind of Unit, which have health, sight radius, strength etc. I want it to be represented on battle field, on the bottom of the screen (avatar with states), and in info window. I also want it to be controlled by player or computer (mind controll). But that's not all: unit also has a Weapon, which also has some stats, and I want to see it on Unit on battlefield and on different tab in info window. Weapon could use different behaviour: semi-automatic, automatic or melee.

Seems like it need MVC. But how do I implement this hierarchy?

I don't use MVC for that, I tend to do something where the various HUD elements listen for an "ObjectSelected" event, then when that event is fired, they look at the object that is currently selected (or passed as part of the event), query for the things they are interested in. (either looking for interfaces or components), and then use that data to update themselves.

Ie, your health display, be it a bar, or text like 156/255, would subscribe to OnObjectSelected, when that event is raised, it would query that object for a Health component, if found it would then look at Health and MaxHealth, and update itself to display it appropriately.

It does mean that the View needs to know about whatever it is it's viewing, and there isn't much in the way of a Controller.

okay, lets say I have another project, where I got some kind of Unit, which have health, sight radius, strength etc. I want it to be represented on battle field, on the bottom of the screen (avatar with states), and in info window. I also want it to be controlled by player or computer (mind controll). But that's not all: unit also has a Weapon, which also has some stats, and I want to see it on Unit on battlefield and on different tab in info window. Weapon could use different behaviour: semi-automatic, automatic or melee.

Seems like it need MVC. But how do I implement this hierarchy?


The first step is recognizing that Weapon should be compositionally a part of the Unit.


struct Weapon
{
     int power;
     float range;
     float firingSpeed;
     enum FiringMode {SemiAutomatic, Automatic};
     FiringMode mode;
     //...other stuff...
     
     AppearanceID appearanceOnUnit;
     TextureID uiThumbnail;
};
 
struct Unit
{
     float health;
     float sightRadius;
     int strength;
     AppearanceID appearance;
     
     Point position;
     Weapon weapon;
};

(Actually, likely there are only a few types of weapons, so you'd just keep them in an array shared by everyone, and the Unit will have a ID for the type of weapon he has)

Then you just do:


Unit *unitCurrentlySelected = nullptr;

//When drawing units:
for(every unit)
{
    if(&unit == unitCurrentlySelected)
    {
        ...draw selection aura...
    }
    
    unit.Draw(destination); //Internally also calls 'weapon.Draw(destination)' to draw the weapon over/under/whatever itself.
}

//When drawing the UI:
if(unitCurrentlySelected)
{
     DrawTexture(posToRenderWeaponThumbnail, Textures.Get(unitCurrentlySelected->weapon.uiThumbnail).FrameFromTime(currentTime));
}
 
//When handling player input:
if(unitCurrentlySelected && mindControlling)
{
     //...mind-control input...
     HandlePlayerInput_ForMindControlledUnits(unitCurrentlySelected);
}
else
{
     //...regular input...
     HandlePlayerInput(input);
}

(Note: this is a rough example, but we make it more complex bit by bit as our needs require)

MVC is particularly important when the Model, View, and Controller all have state. In desktop applications, this is common (even in desktop applications, View and Controller are often put together in one class). With games, this is much less common. With games, the Model has state, but there is very little controller and view state to be worth separating out, except in some cases, for some parts of your game.

For the parts that need it, use it! But for the parts that don't have an overwhelming need for it, you're just bloating your code with needless abstractions and burdensome separations in those areas where the benefit gained from the tradeoff isn't worth the cost.

This is important:

Sometimes the simpler code is actually easier to read and easier to maintain. Sometimes the simpler code is actually easier to debug and easier to optimize too.

You should generally write straightforward and simple code, unless the complexity is actually needed.

Seems like it need MVC.


When you look through blue lenses, the world looks blue.

If you are reading articles that are talking about the significance of MVC, you'll think you need it. Just like how advertising makes people think they need a product because the advertising says how excellent and time-saving that product is.

You certainly don't need MVC there, but it could work. If you have messaging in place then it would be straightforward to register the UI as a listener with the currently selected unit. That way it could simply send an update message any time it makes relevant changes in state. The UI can show what information is appropriate depending on whether the unit belongs to the player or someone else, etc.

Imaginary development doesn't accomplish anything though, and trying to pit supposedly competing patterns against one another will only lead to foolish prejudices. If a thing works in a situation then you use it. If something else (including simply not using the thing) works better then use that instead. Completed real-world projects are infinitely superior to perfect theoretical projects.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

I'm gonna take a side and say drop MVC altogether. The reasons have been stated by those posting before me. All you need to begin with is a simple game loop. Then expand into a entities - component system.

The first step is recognizing that Weapon should be compositionally a part of the Unit.

Yes, that's pretty obvious, in case Unit and Weapon represented as single class. But I want to separate logic from rendering.

//When handling player input:
if(unitCurrentlySelected && mindControlling)
{
//...mind-control input...
HandlePlayerInput_ForMindControlledUnits(unitCurrentlySelected);
}
else
{
//...regular input...
HandlePlayerInput(input);
}

This approach would lead to total disaster. Unit is not only controllable by player, it could be controlled by computer. And for this case there can be different behaviors, like citizen, guard, fast zombie, jumping zombie etc. I want to just plug in this behaviour to Unit instead of making long if or switch statements

This is important: Sometimes the simpler code is actually easier to read and easier to maintain. Sometimes the simpler code is actually easier to debug and easier to optimize too.

You're right! Thats why I want to break code apart. To make it simpler to read, debug and optimize.

Anyway, I would like to know how to put rest things together.

How do I connect them? Am I suppose to put Board and Players Models inside Game Model? If so, how do I attach Views to those Models? Do I need to store GameModel, GameView and GameController in some kind of container class Game? I read a lot about this pattern but can't find some concrete implementations in context of games.


Sure, your 'model' is just whatever classes comprise the basic 'business logic' of your application (in this case, game data).

You don't need to 'attach' views to models as such, but there are different ways you can approach it. Your application might create the relevant view objects whenever it creates the model objects, and will point the view at the model accordingly. I would suggest starting with a single GameView class that renders everything, get that working, then consider how to improve it later.

The reason there isn't a clear guide on how to do this for games is because, as I said at the start, MVC is not for all applications and certainly not for games. It's for UIs, which have a strictly hierarchical layout and structure, both visibly and logically.

This topic is closed to new replies.

Advertisement