Skip to main content
GameDev.net gamedev.net
🔒 Locked

[c++]the game world and mvc

Started by giugio May 14, 2009 at 6:59 AM 17 replies 2.5k views
Original Post
giugio
giugio
Hy. I'm still reading this article: http://www.gamasutra.com/features/20050414/rouwe_01.shtml on the mvc applyed to the game design. I'm not understand: 1)
Quote:
The Controller can't directly change the state of the Entity. Every update the Controller is polled by the Entity and the Entity tries to follow the Controllers instructions. For example, the Controller would never call a MoveTo() function on a Humanoid but instead the Humanoid would poll the Controller's GetDesiredSpeed() function and then try to reach this speed while performing collision detection to make sure not to clip through walls.
Isn't simple that the controller call methods on entity? why this design implementation? 3)how the controller change the return of this methods ? It must have access to the world game for do that!? How the world is rappresented and how the controller have access to it and then change for each entity the result of these methods? 4)how the entities are updated?and how a entity influence other entities? thanks.
SiS-Shadowman
SiS-Shadowman
I hope I can help:

1) Think of a controller as a steering-wheel in your vehicle. You can surely pull it to the left, but it there's a wall then your car won't move to the left, although the controller wants it.

I think the basic though is that what CAN be done should be kept inside the entities, instead of the controller.

2) I'm not sure what your question is. The controller doesn't need to change anything. You can pull the steering-wheel to the left for a long time, even though there's a wall. The same applies to you pressing a key: You can even press it if your character can't go further to the left.

3) A simple thing would be to call update() on each entity. The entities would then try to do what the controllers want, like calling GetDesiredSpeed().
Influencing is very general and I think there is not only one solution to it, because there are a lot of ways entities can influence other entities. Like in a physical way, where one entity pushes the other one around, or one entity telling another entity that it should go away.
giugio
giugio
very thanks SiS-Shadowman.
Quote:
Original post by SiS-Shadowman
I hope I can help:

1) Think of a controller as a steering-wheel in your vehicle. You can surely pull it to the left, but it there's a wall then your car won't move to the left, although the controller wants it.

I think the basic though is that what CAN be done should be kept inside the entities, instead of the controller.

I'm understand ,then these function :getDesiredSpeed(),getSteeringWheel() ecc.. are polled by entities for centralize every command to the entity(the model)and for do only that what can do!

Quote:

2) I'm not sure what your question is. The controller doesn't need to change anything. You can pull the steering-wheel to the left for a long time, even though there's a wall. The same applies to you pressing a key: You can even press it if your character can't go further to the left.

ok.....

Quote:

3) A simple thing would be to call update() on each entity. The entities would then try to do what the controllers want, like calling GetDesiredSpeed().
Influencing is very general and I think there is not only one solution to it, because there are a lot of ways entities can influence other entities. Like in a physical way, where one entity pushes the other one around, or one entity telling another entity that it should go away.


I'm not understand,
but How for example an entities know if there is a collision ?
It must know the world , but there isn't a world rappresentation in the examples.

And...

Each entity is changed by all other entities?
Is not more simple that each entities update a world and each entities is updated by the world?
You what design implementation should advice to me?
Thanks.

ps. but there is a controller object for each entity?How preserve the state of an entities to another?
SiS-Shadowman
SiS-Shadowman
Quote:
Original post by giugio
Quote:

3) A simple thing would be to call update() on each entity. The entities would then try to do what the controllers want, like calling GetDesiredSpeed().
Influencing is very general and I think there is not only one solution to it, because there are a lot of ways entities can influence other entities. Like in a physical way, where one entity pushes the other one around, or one entity telling another entity that it should go away.


I'm not understand,
but How for example an entities know if there is a collision ?
It must know the world , but there isn't a world rappresentation in the examples.


I think in this case you will need to split things up even further:
An entity is something like a character. He can move to certain positions, can shoot people, and stuff like that. That character is visually represented by some sort of model, so the entity could hold a reference (pointer) to that model as a class member. Additionally to represent the character in a physics simulation (google that keyword, you should be able to find good tutorials) it will hold a reference (again a pointer for example) to its physical representation:

class Entity{    Model        *m_pVisualModel;    PhysicsModel *m_pPhysicalModel;};


This is a very basic example, but it should convey what I meant. The entity simple holds references to its various representations. You can put it like this:

An entity represents a certain "thing" in the game logic. A Model visually represents one entity and a PhysicalModel represents a certain entity in a physical simulation.

Quote:

Each entity is changed by all other entities?


That's not exactly what I meant. An entity can be changed by other entities, but that really depends on the relationship of those entities. A car that has a character sitting in a chair certainly controls that character to a certain degree.

Quote:

Is not more simple that each entities update a world and each entities is updated by the world?


What do you mean by that? I can't follow.

Quote:

ps. but there is a controller object for each entity?How preserve the state of an entities to another?


Well, I think so. There should be a controller for each entity. But maybe an entity can also exist without a controller (for example when an entity is literally dead, it will still persist in the world visually and physically, but it wouldn't do that much, unless it's a zombie :)).

What do you mean about the state of one entity to another (entity?) ? Do you mean it's logical relationship or something else?
giugio
giugio
Thanks a lot you are very kind.
then :
1)the entities have this pointer:
Model *m_pVisualModel;
and can entity find collision with this(the model)?

2)How i can create relations between entities?
For example in a rts game two entities that fighting are relationed , but two entities that are in the opposite site of the screen not are relationed !.

Quote:

What do you mean about the state of one entity to another (entity?) ? Do you mean it's logical relationship or something else?


I think that each entity have a state that is the current responce to the input of what the controller would do.
I think my IA controller as a automata state machine (http://en.wikipedia.org/wiki/Automata-Based_Programming ) that get in input all the entities that are related to entity and create a custom responce that is polled(as function return value) by the entities.
The problem is that the controller can't have a state ,because is the entity that know how it was do in the previews update , then the state must be in the model and is that that the entity currently be.
But how i can create this programmable automata?
Thanks.
giugio
giugio
upup
giugio
giugio
Quote:

class Entity
{
Model *m_pVisualModel;
PhysicsModel *m_pPhysicalModel;
};


1)so for example the collision detection is in the class entity , but how and where are rappresented the other meshes and static entities for test the collision?are in the *m_pPhysicalModel or *m_pVisualModel?
also isn't correct to iterate all the other entities(static and no) for test the bounding volumes?

2)Is correct to create relations from meshes?
for example two fighting character are relationed ,what is a good method for create in the code a relation between two or more character?and how traverse all the relations for do operations(visual and non) on characters?

THanks
SiS-Shadowman
SiS-Shadowman
Everything that can be seen and should interact with the world is an entity. If it's physical body remains static or not is not a question here.
The bounding volumes can be created from either of the two, however since the physical model usually tends to be less complex than the graphical model, you want to use the physical model.

I can't really figure your second questions, but you should really look up "Physical Simulation" on google and read that stuff.

You should also start with a real small game and then work your way up. The questions you ask should be answered quickly once you reach that point in development.
Kylotan
Kylotan
Quote:
Original post by giugio
I'm still reading this article:
http://www.gamasutra.com/features/20050414/rouwe_01.shtml
on the mvc applyed to the game design.
I'm not understand:
1)
Quote:

The Controller can't directly change the state of the Entity. Every update the Controller is polled by the Entity and the Entity tries to follow the Controllers instructions.

For example, the Controller would never call a MoveTo() function on a Humanoid but instead the Humanoid would poll the Controller's GetDesiredSpeed() function and then try to reach this speed while performing collision detection to make sure not to clip through walls.

Isn't simple that the controller call methods on entity?
why this design implementation?

Personally I think MVC is completely pointless if you're going to invert the control flow and have the Model querying the Controller. The example given is a false one, as there's no reason the controller can't call a SetDesiredSpeed function on the Model. I've no idea why the writer suggests his method but I think it's a bad suggestion.
giugio
giugio
thanks
giugio
giugio
Now i'm ready to start , but i have a problem:
I have for each entity the rapresentation , the model and the controller.
Are three divided class ?
Or i can create an entity class with 3 encapsulated classes:?
class entity{CController* m_pController;CRapresentation* m_pRapresentation;CModel* m_pModel;}//or{class CRappresentation{....int CRappresentation::ID(){ return m_id;} }class CController{....int CController::ID(){ return m_id;} }//ecc....

what is better?

If i have three divided class how i manage the three class?
I must use a ID for each of the class?
Thanks.
Antheus
Antheus
struct Entity {  Vector3 current_position;  Vector3 velocity;  Vector3 target_position;  void update(float dt) {    if (distance(current_position, target_position) < 0.5f) {      // we have arrived      observer.fire_arrived_at_destination(this);      return;    }    // calculate delta so that it will move this entity    // towards target_position    Vector3 delta = // ...    Vector3 new_position = current_position + delta * dt;    // check for collision and calculate response    if (would_collide(this.aabb, new_position)) {      new_position = clip_at_collision_point(current_position, new_position);      observer.fire_on_collide(this, new_position);    }    current_position = new_position;  }};


struct HumanController {  void update() {    // read keyboard input    // request entity to try to do it    if (key == FORWARD) {      entity.target_position += Vector3(1.0f, 0.0, 0.0);    }  }};


struct View {  void render() {    for (Entity e : entities) {      e.draw();    }  }};


void run() {  while (running) {    for (Controler c : controllers) c.update();    for (Entity e : entities) e.update(delta_time);    view.render();  }}


A very rough draft of how it works.

A controller can be keyboard input or AI. It doesn't directly change values, it merely requests the desired outcome. A Controller can control any entity. So during cinematic, ScriptController can control player character.

View is passive. It renders most recent state.

Model, or entity, performs the changes, and optionally notifies anyone interested in them. For example, controller could be notified that an entity collided with the wall, and would stop ordering it to move forward.


This is one way to approach the design. It may or may not be optimal choice.
aaron_ds
aaron_ds
Quote:
Original post by Antheus
View is passive. It renders most recent state.


http://en.wikipedia.org/wiki/Model-view-controller

Views aren't always passive. Classically they are the HCI, input, output, all of it. Sure a renderer is a view, and sound output is a view, but keyboard input, mouse input, even network traffic can also be modeled as views. Typically when used in applications (let's ignore MVC in web development) MVC uses the observer pattern between controllers and views and models and views. See the wikipedia link above.

Say there was a button view and when it was clicked, the button's text changed.
The execution path would go like this:
User clicks a button
The button view responds by triggering an onClickEvent
The subscribers -controller methods- to the button onClickEvent are invoked (view<->controller observer pattern).
The controller method modifies the model in this case the button's text.
The model responds by trigger an onChangeEvent
The subscribers to the model's onChangeEvent are invoked (model<->view observer pattern), in this case button::updateText().
Button::updateText() reads the new text from the model and refreshes the button's UI appearance.

The classes involved would be a ButtonView, a ButtonTextController, and a ButtonTextModel.

You're using models, views and controllers, but without observation, I'm not sure that this is what people think of when they think of MVC.

aaron_ds
aaron_ds
Quote:
From the OP's article
The role of the Controller is to specify what the Entity should do. The Controller can't directly change the state of the Entity. Every update the Controller is polled by the Entity and the Entity tries to follow the Controllers instructions.

For example, the Controller would never call a MoveTo() function on a Humanoid but instead the Humanoid would poll the Controller's GetDesiredSpeed() function and then try to reach this speed while performing collision detection to make sure not to clip through walls.


Quote:
The Controller can't directly change the state of the Entity.

This is true for MVC, but inverting the flow of controller is not the answer. Fat models are the answer. See Google:Fat Models, Skinny Controllers. The point here is that controllers are not directly manipulating model state a la structs. Models should provide high-level facilities for their manipulation. model.position.x=35; is bad, model.MoveTo(35,0,0); is good. Models with proper encapsulation and a rich API make model testing much easier. See any of the Google links above for consensus.

Quote:
From the OP's article
To make a Humanoid interact with a mounted gun, for example, the HumanoidController implements a function called GetUseObject(). This function is polled every update by the Humanoid.


If MVC is being properly used polling should not happen. That is unless their implementation of the observer pattern uses polling under the hood. But it doesn't sound like their is any observation going on at all here.

The developers here may have gotten some use out of separating out model, view, and controller code, but behaviorally, this is not MVC.
giugio
giugio
Quote:

Model, or entity, performs the changes, and optionally notifies anyone interested in them. For example, controller could be notified that an entity collided with the wall, and would stop ordering it to move forward.


this for me is the reason because the writer in the article on mvc say that the model must poll the controller , in this case the logic of collision is all in the model and if an object collide an obstaclel it don't cross the walls without send any information to the controller.

But in this mode the controller and the model are more separated , and if the controller ia for example take decision it don't know all the input and all the reason for change "idea".
Is possible?
Thanks.
giugio
giugio
i'm not understand how link on code each entity object with the relative controller object with the relative view object.
I must have a class with a collection that hold each controller,view or model object?
But how a controller get it's personal model(entity) and view if the object are scattered?
Thanks.

giugio
giugio
upup
giugio
giugio
Quote:
Original post by Antheus
*** Source Snippet Removed ***

*** Source Snippet Removed ***

*** Source Snippet Removed ***

*** Source Snippet Removed ***

A very rough draft of how it works.

A controller can be keyboard input or AI. It doesn't directly change values, it merely requests the desired outcome. A Controller can control any entity. So during cinematic, ScriptController can control player character.

View is passive. It renders most recent state.

Model, or entity, performs the changes, and optionally notifies anyone interested in them. For example, controller could be notified that an entity collided with the wall, and would stop ordering it to move forward.


This is one way to approach the design. It may or may not be optimal choice.



thanks Antheus, i have 2 question:
1) if i have this controller:
struct HumanController {  void update() {    // read keyboard input    // request entity to try to do it    if (key == FORWARD) {      entity.target_position += Vector3(1.0f, 0.0, 0.0);    }  }};

you write:
// request entity to try to do it
How i know the entity that is related with the controller?
I set a pointer in the initialization of the controller? for example:

struct HumanController {  HumanEntity* pEntity// this is my change of the class   void update() {    // read keyboard input    // request entity to try to do it    if (key == FORWARD) {      pEntity->target_position += Vector3(1.0f, 0.0, 0.0);    }  }};for (int i = 0; i < NUMENTITIES; i++){    HumanEntity * entity = new HumanEntity(...)    HumanController* controller = new HumanController(...)    HumanView* view = new HumanView(...)    controller->pEntity = entity; //this is the change to do?    //and the observer?    collectionController.add(controller);      collectionEntity.add(entity);//ecc...}

and...

2)why you use the observer pattern?
for example:
observer.fire_arrived_at_destination(this);

this fire an event from the entity to the controller?
so the controller know that the entity is arrived then do
something else or relative to the event?

thanks.
Antheus
Antheus
Quote:
Original post by giugio
How i know the entity that is related with the controller?
Up to you.
Quote:
I set a pointer in the initialization of the controller?
That is one way. The whole point is that controller and entity are loosely coupled. You can change entity of a controller (say player controls tank instead of avatar), or that controller can take control of an entity (GM takes over a player, or during cutscene, script controller takes over player avatar).

Quote:
2)why you use the observer pattern?
for example:
observer.fire_arrived_at_destination(this);

this fire an event from the entity to the controller?

In this case, to some logic handler, a script perhaps. This is separate code flow. Controller can be observer as well, but sometimes you might want other types of control.

Again, this is just one way to deal with this.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.