Building Games Using the MVC Pattern – Tutorial and Introduction

One useful architecture pattern in game development is the MVC (model-view-controller) pattern.
It helps separate the input logic, the game logic and the UI (rendering). The usefulness is quickly noticeable in the early stages of any game development project because it allows to change things quickly without too much rework of code in all layers of the application.

The following diagram is the simplest logical representation of the model view controller concept.

Model-View-Controller pattern

Model-View-Controller pattern

Example Usage

In an example game where the player controls a robot the following can happen:

  • 1 – User clicks/taps somewhere on the screen.
  • 2 – The controller handles the click/tap and converts the event into an appropriate action. For example if the terrain is occupied by an enemy, an attack action is created, if it is empty terrain, then a move action is created and finally if the place where the user tapped is occupied by an obstacle, do nothing.
  • 3 – The controller updates the robot‘s (model‘s) state accordingly. If the move action was created, then it changes the position, if the attack, then it fires.
  • 4 – The renderer (view) gets notified about the state changes and renders the world’s current state.

What this all means is, that the models (robots) don’t know anything about how to draw themselves, or how to change their state (position, hit points). They are dumb entities. In Java they are also called POJOs (plain old java objects).
The controller is in charge of changing the models’ state and notify the renderer.
The renderer has to have a reference to the models (robots and any other entities) and their state, in order to draw them.

We know from the typical game architecture that the main loop acts as a super controller, which updates the states and then renders the objects onto the screen many times a second. We can put all the update and rendering into the main loop along with the robots but that would be messy.

Let’s identify the different aspects (concerns) of our games.

The models
  • The droid controlled by the player
  • An arena where the droid can move
  • Some obstacles
  • Some enemies to shoot at
The controllers
  • The main loop and the input handler
  • Controller to process player input
  • Controller to perform actions on the player’s robot (move, attack)
The views
  • The world renderer – to render the objects onto the screen

Creating the Project

For simplicity I have chosen the applet this time and will try to keep it very brief. The project has the following structure:

MVC - Project structure

MVC - Project structure

The file Droids.java is the applet and contains the main loop.

package net.obviam.droids;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Droids extends Applet implements Runnable {

	private static final long serialVersionUID = -2472397668493332423L;

	public void start() {
		new Thread(this).start();
	}

	public void run() {
		
		setSize(480, 320); // For AppletViewer, remove later.

		// Set up the graphics stuff, double-buffering.
		BufferedImage screen = new BufferedImage(480, 320, BufferedImage.TYPE_INT_RGB);
		Graphics g = screen.getGraphics();
		Graphics appletGraphics = getGraphics();

		long delta = 0l;
		
		// Game loop.
		while (true) {
			long lastTime = System.nanoTime();

			g.setColor(Color.black);
			g.fillRect(0, 0, 480, 320);

			// Draw the entire results on the screen.
			appletGraphics.drawImage(screen, 0, 0, null);

			// Lock the frame rate
			delta = System.nanoTime() - lastTime;
			if (delta < 20000000L) {
				try {
					Thread.sleep((20000000L - delta) / 1000000L);
				} catch (Exception e) {
					// It's an interrupted exception, and nobody cares
				}
			}
			if (!isActive()) {
				return;
			}
		}
	}

	public boolean handleEvent(Event e) {
		return false;
	}
}

Running the above code as an applet does nothing more than setting up the main loop and painting the screen black.

There are 3 packages in the structure and the respective components will go there.
net.obviam.droids.model will contain all the models
net.obviam.droids.view will contain all the renderers
net.obviam.droids.controller will contain all the controllers

Creating the models

The Droid

Droid.java

package net.obviam.droids.model;

public class Droid {

	private float x;
	private float y;
	private float speed = 2f;
	private float rotation = 0f;
	private float damage = 2f;
	
	public float getX() {
		return x;
	}
	public void setX(float x) {
		this.x = x;
	}
	public float getY() {
		return y;
	}
	public void setY(float y) {
		this.y = y;
	}
	public float getSpeed() {
		return speed;
	}
	public void setSpeed(float speed) {
		this.speed = speed;
	}
	public float getRotation() {
		return rotation;
	}
	public void setRotation(float rotation) {
		this.rotation = rotation;
	}
	public float getDamage() {
		return damage;
	}
	public void setDamage(float damage) {
		this.damage = damage;
	}
}

It is a simple java object without any knowledge of the surrounding world. It has a position, rotation, speed and damage. These states are defined by the member variables and are accessible through the getter and setter methods.

The game requires a few more models: obstacles and enemies on a map. For simplicity the obstacles will have just a position on the map and the enemies will be standing objects. The map will be a 2 dimensional array holding the enemies, obstacles and the droid. The map will be called Arena to differentiate from the standard Java map and will be populated with obstacles and enemies when it is constructed.

Obstacle.java

package net.obviam.droids.model;

public class Obstacle {

	private float x;
	private float y;

	public Obstacle(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public float getX() {
		return x;
	}
	public float getY() {
		return y;
	}
}

Enemy.java


package net.obviam.droids.model;

public class Enemy {

	private float x;
	private float y;
	private int hitpoints = 10;
	
	public Enemy(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public float getX() {
		return x;
	}
	public float getY() {
		return y;
	}
	public int getHitpoints() {
		return hitpoints;
	}
	public void setHitpoints(int hitpoints) {
		this.hitpoints = hitpoints;
	}
}

Arena.java

package net.obviam.droids.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Arena {
	
	public static final int WIDTH = 480 / 32;
	public static final int HEIGHT = 320 / 32;
	
	private static Random random = new Random(System.currentTimeMillis());

	private Object[][] grid;
	private List<Obstacle>	obstacles = new ArrayList<Obstacle>();
	private List<Enemy>		enemies = new ArrayList<Enemy>();
	private Droid droid;
	
	public Arena(Droid droid) {
		this.droid = droid;

		grid = new Object[HEIGHT][WIDTH];
		for (int i = 0; i < WIDTH; i++) {
			for (int j = 0; j < HEIGHT; j++) {
				grid[j][i] = null;
			}
		}
		// add 5 obstacles and 5 enemies at random positions
		for (int i = 0; i < 5; i++) {
			int x = random.nextInt(WIDTH);
			int y = random.nextInt(HEIGHT);
			while (grid[y][x] != null) {
				x = random.nextInt(WIDTH);
				y = random.nextInt(HEIGHT);
			}
			grid[y][x] = new Obstacle(x, y);
			obstacles.add((Obstacle) grid[y][x]);
			while (grid[y][x] != null) {
				x = random.nextInt(WIDTH);
				y = random.nextInt(HEIGHT);
			}
			grid[y][x] = new Enemy(x, y);
			enemies.add((Enemy) grid[y][x]);
		}
	}
	
	public List<Obstacle> getObstacles() {
		return obstacles;
	}
	public List<Enemy> getEnemies() {
		return enemies;
	}
	public Droid getDroid() {
		return droid;
	}
}

The Arena is a more complex object but reading through the code should make it easy to understand. It basically groups all the models together into a single world. Our game world is the arena which contains all the elements like our droid, enemies and obstacles.
The WIDTH and HEIGHT are calculated based on the resolution I have chosen. A cell (tile) on the grid will be 32 pixels wide and tall so I just compute how many cells go onto the grid.

In the constructor (line #19) the grid is set up and 5 obstacles and 5 enemies are randomly placed. This will make up the starting arena and our game world.

In order to keep the main loop tidy, we’ll delegate the update and rendering to the GameEngine. This is a simple class that will process the user input, update the states of the models and will render the world. It is a tiny glue framework to make all these happen.

The GameEngine.java stub

package net.obviam.droids.controller;

import java.awt.Event;
import java.awt.Graphics;

public class GameEngine {

	/** handle the Event passed from the main applet **/
	public boolean handleEvent(Event e) {
		switch (e.id) {
		case Event.KEY_PRESS:
		case Event.KEY_ACTION:
			// key pressed
			break;
		case Event.KEY_RELEASE:
			// key released
			break;
		case Event.MOUSE_DOWN:
			// mouse button pressed
			break;
		case Event.MOUSE_UP:
			// mouse button released
			break;
		case Event.MOUSE_MOVE:
			// mouse is being moved
			break;
		case Event.MOUSE_DRAG:
			// mouse is being dragged (button pressed)
			break;
		}
		return false;
	}
	
	/** the update method with the deltaTime in seconds **/
	public void update(float deltaTime) {
		// empty
	}
	
	/** this will render the whole world **/
	public void render(Graphics g) {
		// empty
	}
}

To use the engine the Droids.java class needs to be modified. We need to create an instance of the GameEngine class and call the update() and render() methods at the appropriate times. Also we need to delegate the input processing to the engine.

Add the following lines:
Declare the private member and also instantiate it.

	private GameEngine engine = new GameEngine();

The modified game loop looks like this:

		while (true) {
			long lastTime = System.nanoTime();

			g.setColor(Color.black);
			g.fillRect(0, 0, 480, 320);

			// Update the state (convert to seconds)
			engine.update((float)(delta / 1000000000.0));
			// Render the world
			engine.render(g);
			
			// Draw the entire results on the screen.
			appletGraphics.drawImage(screen, 0, 0, null);

			// Lock the frame rate
			delta = System.nanoTime() - lastTime;
			if (delta < 20000000L) {
				try {
					Thread.sleep((20000000L - delta) / 1000000L);
				} catch (Exception e) {
					// It's an interrupted exception, and nobody cares
				}
			}
		}

The highlighted lines (#7-#10) contain the delegation to the update() and render() methods. Note that there is a conversion to seconds from nano seconds. It’s very useful to work in seconds as we can work with real world values.
Important: The update needs to happen after the delta (time elapsed since the last update) has been calculated. Also the render should be called after the update so it will display the current state of the objects. Note that the screen is cleared each time before the render (painted black).

The last thing to be done is to delegate the input handling.
Replace the current handleEvent method with the following snippet:

	public boolean handleEvent(Event e) {
		return engine.handleEvent(e);
	}

Very simple straightforward delegation.

Running the applet yields no particular exciting result. Just a black screen. It makes sense as everything is just a stub apart from the screen being cleared every cycle.

Initialising the models (world)

Our game needs a droid and some enemies. By design, the world is our Arena. By instantiating it, we have created a world (check the constructor in Arena).

We will create the world in the GameEngine as the engine is responsible for telling the view what to render.
We also need the Droid to be created here because the Arena requires it its constructor. Is good to have it separate as the droid will be controlled by the player.

Add the following members to the GameEngine along with the constructor which initialises the world.

	private Arena arena;
	private Droid droid;

	public GameEngine() {
		droid = new Droid();
		// position droid in the middle
		droid.setX(Arena.WIDTH / 2);
		droid.setY(Arena.HEIGHT / 2);
		arena = new Arena(droid);
	}

Note: Arena‘s constructor needs to be modified, so the Droid gets added to the grid before the obstacles and enemies.

...
		// add the droid
		grid[(int)droid.getY()][(int) droid.getX()] = droid;
...

Running the applet again, won’t change the output but we have our world created. We can add logging to see the result but that won’t be interesting. Let’s create our first view which will reveal our world.

Creating the first View/Renderer

We’ve put a lot of effort in creating the arena and world, we’re eager to actually see it. Because of this, we will create a quick and dirty renderer to reveal the world. By quick and dirty I mean no fancy images or anything but simple squares, circles and placeholders. Once we are happy that the game elements are in we can work on a more elaborate view to replace the squares and circles with fancy graphics. This is where the power of decoupling shines.

Steps to render the world.

  • Draw the grid to see where the cells are.
  • Obstacles will be drawn as blue squares and they will occupy the cells
  • Enemies will be red circles
  • The droid will be a green circle with a brown square

First we create the renderer interface. We use this to establish a single way to interact with the renderer and it will make it easy to create more views without affecting the game engine. To read more on why is a good idea check this and this.

Create an interface in the view package.
Renderer.java

package net.obviam.droids.view;

import java.awt.Graphics;

public interface Renderer {
	public void render(Graphics g);
}

That is all. It contains one single method: render(Graphics g). The Graphics g is the canvas that is passed from the applet. Ideally the interface will be agnostic of this and each implementation will use a different back-end but the purpose of this exercise is to describe the MVC not to create a full framework. Because we have chosen applet we need the Graphics object.

The concrete implementation looks like this:
SimpleArenaRenderer.java (in the view package)

package net.obviam.droids.view;

import java.awt.Color;
import java.awt.Graphics;

import net.obviam.droids.model.Arena;
import net.obviam.droids.model.Droid;
import net.obviam.droids.model.Enemy;
import net.obviam.droids.model.Obstacle;

public class SimpleArenaRenderer implements Renderer {

	private Arena arena;
	
	public SimpleArenaRenderer(Arena arena) {
		this.arena = arena;
	}
	
	@Override
	public void render(Graphics g) {
		// render the grid
		int cellSize = 32; // hard coded
		g.setColor(new Color(0, 0.5f, 0, 0.75f));
		for (int i = 0; i <= Arena.WIDTH; i++) {
			g.drawLine(i * cellSize, 0, i * cellSize, Arena.HEIGHT * cellSize);
			if (i <= Arena.WIDTH)
				g.drawLine(0, i * cellSize, Arena.WIDTH * cellSize, i * cellSize);
		}
		
		// render the obstacles
		g.setColor(new Color(0, 0, 1f));
		for (Obstacle obs : arena.getObstacles()) {
			int x = (int) (obs.getX() * cellSize) + 2;
			int y = (int) (obs.getY() * cellSize) + 2;
			g.fillRect(x, y, cellSize - 4, cellSize - 4);
		}
		
		// render the enemies
		g.setColor(new Color(1f, 0, 0));
		for (Enemy enemy : arena.getEnemies()) {
			int x = (int) (enemy.getX() * cellSize);
			int y = (int) (enemy.getY() * cellSize);
			g.fillOval(x + 2, y + 2, cellSize - 4, cellSize - 4);
		}
		
		// render player droid
		g.setColor(new Color(0, 1f, 0));
		Droid droid = arena.getDroid();
		int x = (int) (droid.getX() * cellSize);
		int y = (int) (droid.getY() * cellSize);
		g.fillOval(x + 2, y + 2, cellSize - 4, cellSize - 4);
		// render square on droid
		g.setColor(new Color(0.7f, 0.5f, 0f));
		g.fillRect(x + 10, y + 10, cellSize - 20, cellSize - 20);
	}
}

Lines #13 – #17 declare the Arena object and make sure that it is set when the renderer is constructed. I called it ArenaRenderer because we will render the arena (world).
The only method in the renderer is the render() method. Let’s see what it does step by step.
#22 – Declare a cell size in pixels. It is 32. It’s hard coded as in the Arena class.
#23 – #28 – The grid is being drawn. It is a simple grid. First the colour is set to dark green and lines are drawn at equal distance.
Drawing the obstacles – blue squares
#31 – Set the brush color to blue.
#32 – #36 – Iterate through all the obstacles in the arena and for each it draws a blue filled rectangle slightly smaller than the cell on the grid.
#39 – #44 – Sets the color to red and by iterating through the enemies in the arena, it draws a circle at the respective position.
#47 – #54 – Finally draws the droid as a green circle with a brown square on top.

Note that the arena in the real world has a width of 15 (480 / 32). So the droid will always be at the same position (7, 5) and the renderer works out its position on the screen by using a unit measure conversion. In this case is 1 unit in world coordinate is 32 pixels on the screen.

By modifying the GameEngine to use the newly created view (SimpleArenaRenderer) we get the result.

public class GameEngine {

	private Arena arena;
	private Droid droid;
	private Renderer renderer;
	
	public GameEngine() {
		droid = new Droid();
		// position droid in the middle
		droid.setX(Arena.WIDTH / 2);
		droid.setY(Arena.HEIGHT / 2);
		arena = new Arena(droid);
		
		// setup renderer (view)
		renderer = new SimpleArenaRenderer(arena);
	}
	
	/** ... code stripped ... **/
	
	/** this will render the whole world **/
	public void render(Graphics g) {
		renderer.render(g);
	}
}

Pay attention to the highlighted lines (5, 15, 22). These are the lines where the renderer (view) is added to the game.

The result should look like the following image (the positions are random apart from the player’s droid):

The result of the first view


This is a great view to test out the arena and see the models. It’s extremely easy to create a new view that instead of shapes (squares and circles) displays actual sprites.

Controller for Handling Input and Update Models

So far the game does nothing but displays the current state of the world (arena). For simplicity we will update just one state of the droid, its position.
The steps to move the droid based on user input are:

  • On mouse up check if the clicked cell on the grid is empty. This means that it does contain any objects which can be Enemy or Obstacle instances.
  • If the cell is empty, the controller will create an action that will move the droid at a constant speed until it reaches the destination.
package net.obviam.droids.controller;

import net.obviam.droids.model.Arena;
import net.obviam.droids.model.Droid;

public class ArenaController {

	private static final int unit = 32;
	private Arena arena;
	
	/** the target cell **/
	private float targetX, targetY;
	/** true if the droid moves **/
	private boolean moving = false;
	
	public ArenaController(Arena arena) {
		this.arena = arena;
	}
	
	public void update(float delta) {
		Droid droid = arena.getDroid();
		if (moving) {
			// move on X
			int bearing = 1;
			if (droid.getX() > targetX) {
				bearing = -1;
			} 
			if (droid.getX() != targetX) {
				droid.setX(droid.getX() + bearing * droid.getSpeed() * delta);
				// check if arrived
				if ((droid.getX() < targetX && bearing == -1)
						|| (droid.getX() > targetX && bearing == 1)) droid.setX(targetX);
			}
			// move on Y
			bearing = 1;
			if (droid.getY() > targetY) {
				bearing = -1;
			} 
			if (droid.getY() != targetY) {
				droid.setY(droid.getY() + bearing * droid.getSpeed() * delta);
				// check if arrived
				if ((droid.getY() < targetY && bearing == -1)
						|| (droid.getY() > targetY && bearing == 1)) droid.setY(targetY);
			}
			// check if arrived
			if (droid.getX() == targetX && droid.getY() == targetY) 
				moving = false;
		}
	}
	
	/** triggered with the coordinates every click **/
	public boolean onClick(int x, int y) {
		targetX = x / unit;
		targetY = y / unit;
		if (arena.getGrid()[(int) targetY][(int) targetX] == null) {
			// start moving the droid towards the target
			moving = true;
			return true;
		}
		return false;
	}
}

The following breakdown explains the logic and important bits.
#08 – The unit represents how many pixels are in a cell which represents 1 unit in world coordinates. It’s hard-coded and not optimal but for the demo is good enough.
#09 – The Arena the controller will control. It is set when the controller is constructed (line #16).
#12 – The target coordinates of the click in world units.
#14 – It is true when the droid is moving. This is the “move” actions’ state. Ideally this should be a stand alone class, but to demonstrate the controller and keep it concise, we’ll hack an action together inside the controller.
#20 – The update method that updates the position of the droid according to the time passed at a constant speed. It is extremely simple, it checkes both X and Y positions and if they are not the same as the target position, it updates the droid’s respective position (X or Y) considering its speed. If the droid is in the target position, then the move state variable is updated completing the move action.
This is not a very well written action, there is no collision checking on obstacles or enemies found along the way, no path finding. It just updates state.
#52 – The onClick(int x, int y) method will be called when the “mouse up” event occurs. It checks if the clicked cell is empty and if so, then it starts the “move” action by setting the state variable to true
#53-#54 – Converts screen coordinates to world coordinates.

This is the controller. To use it, the GameEngine needs to be updated.
The updated GameEngine.java

package net.obviam.droids.controller;

import java.awt.Event;
import java.awt.Graphics;

import net.obviam.droids.model.Arena;
import net.obviam.droids.model.Droid;
import net.obviam.droids.view.Renderer;
import net.obviam.droids.view.SimpleArenaRenderer;

public class GameEngine {

	private Arena arena;
	private Droid droid;
	private Renderer renderer;
	private ArenaController controller;
	
	public GameEngine() {
		droid = new Droid();
		// position droid in the middle
		droid.setX(Arena.WIDTH / 2);
		droid.setY(Arena.HEIGHT / 2);
		arena = new Arena(droid);
		
		// setup renderer (view)
		renderer = new SimpleArenaRenderer(arena);
		// setup controller
		controller = new ArenaController(arena);
	}
	
	/** handle the Event passed from the main applet **/
	public boolean handleEvent(Event e) {
		switch (e.id) {
		case Event.KEY_PRESS:
		case Event.KEY_ACTION:
			// key pressed
			break;
		case Event.KEY_RELEASE:
			// key released
			break;
		case Event.MOUSE_DOWN:
			// mouse button pressed
			break;
		case Event.MOUSE_UP:
			// mouse button released
			controller.onClick(e.x, e.y);
			break;
		case Event.MOUSE_MOVE:
			// mouse is being moved
			break;
		case Event.MOUSE_DRAG:
			// mouse is being dragged (button pressed)
			break;
		}
		return false;
	}
	
	/** the update method with the deltaTime in seconds **/
	public void update(float deltaTime) {
		controller.update(deltaTime);
	}
	
	/** this will render the whole world **/
	public void render(Graphics g) {
		renderer.render(g);
	}
}

The changes are highlighted.
#16 – Declare the controller.
#28 – Instantiate the controller.
#46 – Delegating the mouse up event.
#60 – Call the update method on the controller.

Run the applet and you can click on the map and if the cell is empty, the droid will move there.

Excercises

  • Create a view that will display images/sprites for entities instead of the drawn shapes.
    Hint: Use BufferedImage to achieve that.
  • Extract the move action into a new class.
  • Add new actions (attack) when an enemy is clicked
    Hint:Create a bullet entity that gets fired to the target. You can use the move action with a higher speed. When the hitpoint gets down to 0, then the enemy is destroyed. Use a different image to represent different states.

Source Code

https://github.com/obviam/mvc-droids or download as zip file.
You can also use git
$ git clone git://github.com/obviam/mvc-droids.git
LinkedInRedditTumblrDiggTechnorati FavoritesShare

19 Responses - Add Yours+

  1. Pinky says:

    Can anyone give an example of how to use BufferedImage to replace the drawn graphics with local .jpg files?

    Every webpage I search for does this a different way and none of them seem to work for me. Some people are using something called an ImageObserver, some are using a MediaTracker. Some are using Image, some BufferedImage. Some people convert from one to the other. Some use URLs for the image some use local files. Everything I have tried fails. I feel like I am just throwing darts at a dartboard in the dark here.

  2. Daniel Klava says:

    Hello there!

    I’m having trouble porting it to Android. I’m trying to use the basic loop you explained in the other post with the MVC Pattern explained here, and learning a lot with it, but I got a little stuck. What would be a simple way to accomplish this, if I may ask?

    Thanks in advance!

  3. Chris S says:

    There is a slight glitch, if you are moving and then click on an enemy the Droid can move on top of an enemy. This happens because the onClick method changes the targetX and targetY before actually checking if it can move there.

    Just a heads up, but otherwise this is GREAT. Thanks!

  4. Thomas says:

    Loved this tutorial, I’ve been using MVC for many years on the web and love how the pattern can be used for realtime games.

    Great work!

  5. jayjay says:

    I am trying to implement: “Add new actions (attack) when an enemy is clicked”.
    Is this possible without using instaceof?

    • Impaler says:

      You can have the entities implement a Clickable interface with an onClicked() method.
      The enemy will signal the engine that it was clicked and can issue the attack.
      This is a very simple method to circumvent if-else statements. Make it an event base engine.

  6. Deneidez says:

    Actually model should have logic. Otherwise model would need controller to be fully working. All of them model, view and controller should work alone too(Of course for example view couldn’t show anything, but it would still work.).

    Just think about different platforms. For example PC, consoles and touchscreen mobile phones. All those need different kind of controller. If there is any logic in controller that affects how program logic works, you would have to duplicate it for each platform and that is something one shouldn’t do.

    • Impaler says:

      Don’t mix the term ‘controller’ in the physical sense as in keyboard, touch-screen or gamepad with the ‘controller’ in the MVC pattern.
      Indeed, the physical controllers are platform dependant and ideally they will create ‘actions’ that will update the affected models’ states (internal variables).
      In the pure MVC pattern the models are nothing more than data carriers and they have no idea whatsoever of the surrounding world. They are dumb. For collision detection for example, one will have to create a whole collision manager that will check if each model collides with an other and if so then it will issue an ‘action’ which will change the state of the model instead of the model updating this information.
      Of course there is no problem giving some sense to the models and make them ‘aware’ of things but that is not the pure MVC model which I was trying to demonstrate. Even if a model will have logic, it is best done with behaviours (check The Strategy Pattern ) which essentially gives controllers to the models.
      It is very extensible and decoupled.
      The controller in MVC is a piece of code that controls the models.
      The controller on a device is an equipment that gives input data for the controller in the game to control the models.
      Hope that clears it up a bit.

      • Deneidez says:

        No, I am not mixing stuff. If you read the original papers or be taught by someone who’s knowledge is based on original papers(or who has used nothing but rails… pun intended ;) ), you might think that model is only for data.

        http://heim.ifi.uio.no/~trygver/1979/mvc-1/1979-05-MVC.pdf
        http://heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf

        However controller should have as little business logic as possible, because it should do nothing but take input and send it as a action for model. There is a ‘joke’ about it too and it goes like “Skinny controller, fat model.”.

        Just think about it. If you use string to communicate with model, you could easily replace controller with telnet wrapper or something and not to care about business logic, because its there already. :)

        • Impaler says:

          I agree on this somewhat, and maybe it didn’t come out clear enough as I have thought.
          What controls the models (meaning updates the attributes) is the game engine (business logic). The controller in the MVC sense is just the input received and triggers some actions on the game.
          Like, ‘move droid to this point’ is a consequence of the game engine interpreting an onClick event or a network message (over telnet as you say). The controller just needs to delegate a message and from here on it is the game engine’s (business layer in enterprise software) responsibility to carry out the actions. If you choose to put that in the model (droid) itself is up to you, but it’s better to have a dedicated layer that updates the models than the models having to that for themselves. When the model gets logic it becomes an intelligent agent not just a data bearing entity.
          Also giving logic to perform for models will make it difficult to create entity systems as their behaviour is hard-coded.
          Both ways have pros and cons so I don’t argue what you’re saying. And also I think one has to be sensitive on what he/she tries to achieve. For very complex AIs the overhead of adding behaviour is too much sometimes and probably it is better to have them programmed directly in the model. You would still call the game engine right?
          I won’t hold rails against you :)
          I come from a very multi tiered web apps background and understand the ror way and there are quite a few similarities. I used Grails too.

          • Deneidez says:

            I shouldn’t argue on the internet… But because I am on lunch break and bit bored, here it is.

            I see now what was wrong in your mvc. MODEL in mvc isn’t the same thing as model(s) in web frameworks(like for example django models, they are more like templates for entities and controller is view etc. Its a mess and they don’t even admit it.). MODEL in mvc is fully functioning program as a black box, which you can use with different methods/functions/procedurals. It doesn’t show anything and it can be controlled only by using methods/functions/procedurals it has. Lets take that first list on this page and modify it to follow mvc more properly.

            1 – User clicks/taps somewhere on the screen.
            2 – The controller polls view did that click/tap hit something. If poll returns an enemy, an attack action is created, if it is empty terrain, then a move action is created and finally if the place where the user tapped is occupied by an obstacle or some disabled gui component etc. , do nothing.
            3 – The controller tells MODEL about the action.
            4 – If MODEL gets move action, it tries to move currently selected robot(s). If enemy gets in the same position where robots tried to move or it gets otherwise blocked, MODEL knows that it can’t move currently selected robot(s) there and will do nothing or makes robots attack enemy etc.(whatever according to business logic). If MODEL gets attack action all currently selected robot(s) try to fire enemy.
            4 – The view(renderer is part of view) polls current state and all stuff like robot positions, enemy positions etc.(basically eveything it needs to render current frame) from MODEL and renders frame according to data.

          • Deneidez says:

            Yes, it is on wikipedia too. :)

            “The model is not necessarily merely a database; the ‘model’ in MVC is both the data and the business/domain logic needed to manipulate the data in the application.”

  7. Gabriel says:

    Thank you very much, Impaler, for your continued effort in keeping this website current and for sharing your insight on game development. I hope your work towards this and your projects pays off for you. I look forward to your future posts.

    Keep it up!

  8. [...] (especially Bob) and we will introduce some controllers too. To read more on the MVC pattern, check out my other article or search for it on the net. It’s very [...]

  9. ano says:

    Thanks for putting all the effort into writing these articles for us ;) Looking forward to your next one :)

  10. Peter says:

    Great to see you back again.

  11. Derrik Curran says:

    Yeah, you should absolutely write a book. I’d buy it.

  12. jimcracks says:

    I was afraid you had lost interest. Please continue to share your knowledge! Your articles are fantastic. You need to write a book! I’ve haven’t had much time for android game development (too much of my time using MVC for corporate crap), but trying to get back into it. It seems to be a perfect article for that. I’m a little confused why you wrote an applet, but will probably learn more trying to convert it to Android anyway.
    All Hail the Impaler!