Model View Control

Hi,

And about Model View Control on a game engine?

Use MVC on entire project or only on the game layer?

Or all of this it's waste of time?

Tks :)
Here are few questions on MVC and answers from Casey on stream:
https://hero.handmade.network/episode/code/day217#3833
https://hero.handmade.network/episode/chat/chat001#2291


Edited by Mārtiņš Možeiko on
MVC and all the related MV* patterns IME boil down to the same thing:

A model with the data you want to expose through an interface (the View). The interface can be a GUI, a C-api, a web-api, ... It is usually standardized in some way and dependent on the usage of it. So it makes sense to separate the model's design from the View's.

To expose the model through that view you need some glue code that's the "controller" or "view-model" or "presenter".

It doesn't matter how you name that glue code or which minutia change between them it's still a bunch of data and operations on that data getting exposed through an interface.

I have done the hard separation between model and GUI code before by separating the projects and only having a dependency going one way. Using that I have been able to reuse the model code wholesale in related projects that needed to read the files the first project wrote out.

mmozeiko
Here are few questions on MVC and answers from Casey on stream:
https://hero.handmade.network/episode/code/day217#3833
https://hero.handmade.network/episode/chat/chat001#2291


Hi,

I watched the first video, the Casey talk very cleary, 90% ot time I understand, but my ears it's not so good to understand english, my write sucks also, but I read very well.

But now with the second video and I watch again, again and again the first, I understand.

Thanks for the help again :)
ratchetfreak
MVC and all the related MV* patterns IME boil down to the same thing:

A model with the data you want to expose through an interface (the View). The interface can be a GUI, a C-api, a web-api, ... It is usually standardized in some way and dependent on the usage of it. So it makes sense to separate the model's design from the View's.

To expose the model through that view you need some glue code that's the "controller" or "view-model" or "presenter".

It doesn't matter how you name that glue code or which minutia change between them it's still a bunch of data and operations on that data getting exposed through an interface.

I have done the hard separation between model and GUI code before by separating the projects and only having a dependency going one way. Using that I have been able to reuse the model code wholesale in related projects that needed to read the files the first project wrote out.


Hi, the last 10 years I programming on PHP, now I returning to programming on c/c++ to learn to make a game, because this, what I thinking now can be very wrong.

I concert with you about MVC and how to do.

I do my own framework using MVC on PHP and this help me a lot.


Ok, I trying a idea here, but I don't know if this a good idea.

[CORE]
The game engine.

Router:
Where are the main loop.
Will control the call of the child-controls, your life time, your constructs and destructs.

Control:
Have the tools to child-control make you job, read all the inputs, call child-models and child-views, control some the statements, thinks to help on decisions.

Model
Tools to help child-models like, load assets (image, audio, xml, etc), save files, interpret scripts, serialize of data, memory, convert datas

View
Tools to help child-views like, make the window, rendering all the things, animate, play the sound, make the controller shake, light, shades, fonts

[childs]
The game, can be a scene, menu, action, etc...



A example of this things



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class SceneIntro_model : public Model{
public:
    int loadMap32(){
       this->loadOBJ('texture.bmp');
       this->loadIMG('texture.bmp');
       //some calc
       this->rules();
    }
    int newJump(){
       //some math
    }
private
    int rules(){
       this->loadXML('mechanics.xml');
       //make some calcs
    }
}


class SceneIntro_view : public View{
public:
    int makeMap32(){
       //put objects, make the math happen
       //put the result of the calcs
       this->light();
    }
    int jump(){
       //put objects, make the math happen
       //put the result of the calcs
       this->light();
    }
private
    int light(){
       this->changecolor(bla bla bla);
       this->putLight(x,x,x,x,x);
    }
}


class SceneIntro_control : public Control{
    int index(){
        //This can be a function of the main Control like this->loadModel('name');
        this->model= new SceneIntro_model ();
        this->view= new SceneIntro_view ();


        this->model->loadMap32();
        if(this->controller(Press_X)){
            this->model->newJump();
            this->view->jump();
        }
        this->view->makeMap()
        this->view->render();
    }
}


class Router{
    Init(){
        SceneIntro_control *control;
	control = new SceneIntro_control ();
	control->index();
    }
}

Edited by unfear on
Oh, brother, you've got some unlearning to do.

Can you explain how this ceremonial glue code reduces the amount of work you have to do to ship a game?
Or improves your game in any other meaningful way?

Whenever somebody mentions MVC, i haven't got a slightest clue what they are talking about exactly. I go blank.
It's meaningless terminology.

I can understand there being multiple representations of basically the same data,
such as data structure used in level editor, and data struct (or the "model") used in-game.
Or the data layout of level as saved to the disk.

Consequently there is code which does a transform between these represantations.
And there might even be some code which decides which representation should be shown.

Oh boy, that sounds awful lot like common-sense doesn't it?

It's one of these "software patterns" that shouldn't even have a name for it.

It's the sort of terminology an academic would come up to pat himself on the back on how smart he is.
Then he writes a book. Now he's invited to do talks introducing MVC to the uninitiated.
Finally he has secured himself with endless supply of consulting gigs. Life is good.



Edited by pragmatic_hero on
I kind of have to agree with pragmatic_hero. All time you spend on thinking about these things, and structuring this way, is time you could have spent focusing on the software you are making. We focus to much on code, and to little on our products in my opinion, and that tends to be even more true for people that try to program in a dogmatic way, like MVC.

Everything is data, no matter if it is input, manipulating other data, or output. Try to stop thinking dogmatic, and try to let things come oganically. It may make things Messier at first, but I think the win is huge in the long run.
Tks for the replies :)

@Telash:

All my experience with MVC comes from web developer with PHP, never trying this on C/C++.

On PHP, MVC help me a lot with the productivity, it's more easy to change or add more stuff, it's a swap, spend more time on a code to code less on the future.

But I really don't know if it's a good idea to a game engine (not a IDE), everything can be does with structured method only, this is a fact, I just only asking and trying to learn about this.



@pragmatic_hero:
I try to explain with words but I don't know, so I make this draw to trying to explain the idea.

https://unfear.com.br/__arquivos/mvcidea.png

My experience is that what is good in games, is good in other applications, and vice versa. I write Glyphin the same way I did games before. Only difference is: way more allocations in Glyphin.

However, the big difference I think, is, whats good in C, may not be good in PHP, and vice versa.
My only real advice is: code code code! And accept the fact that your first game or 2 will collapse under their own weight. But you will learn on a depth that a book, we in the forum, tutorials, or the Univeristy would never even come close.
Telash
My experience is that what is good in games, is good in other applications, and vice versa. I write Glyphin the same way I did games before. Only difference is: way more allocations in Glyphin.

However, the big difference I think, is, whats good in C, may not be good in PHP, and vice versa.
My only real advice is: code code code! And accept the fact that your first game or 2 will collapse under their own weight. But you will learn on a depth that a book, we in the forum, tutorials, or the Univeristy would never even come close.


No no no, I'm a smart guy, I'll follow you advice :)

Maybe you should try to make a simple game using "MVC" and then try to make the same game but without forcing an architecture to see what works for you, what is more complicated, how much time it took... I think it's important to try doing both because no matter how much somebody tells you what is good or not, you will not understand it unless you do it yourself.

The example code you gave in my opinion contains unnecessary indirection because you are forcing the game into an architecture (the MVC) instead of letting the game "tell you" the architecture it needs. Here is a example of one way to organize your code for a game.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
enum Mode {
    Mode_intro,
    Mode_game,
}

struct IntroData { ... };

struct GameData {
    r32 pos_x;
    r32 pos_y;
    r32 vel_x;
    r32 vel_y;
};

void game_input( GameData* game ) {

    if ( input_justPressed( "jump" ) ) {
        game->vel_y = 10.0f;
    }
}

void game_simulate( GameData* game ) {

    game->pos_y += game->vel_y * deltaTime;
    game->vel_y += gravity * deltaTime;
}

void game_render( GameData* game ) {
    drawSprite( game->pos_x, game->pos_y );
}

int main( int argc, char** argv ) {
    
    bool running = true;
    Mode mode = Mode_intro;
    GameData gameData = { 0 };
    IntroData introData = { 0 };
    
    while ( running ) {
        
        switch ( mode ) {
            
            case Mode_intro: {
                
                intro_input( &introData );
                intro_simulate( &introData );
                intro_render( &introData );
                
            } break;
            
            case Mode_game: {
                
                game_input( &gameData );
                game_simulate( &gameData );
                game_render( &gameData );
                
            } break;
        }
    }
    
    return 0;
}



Edited by Simon Anciaux on Reason: Typo