Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Game Logic Placement (Command or Proxy)  (Read 8039 times)
andres
Jr. Member
**
Posts: 14


View Profile Email
« on: November 27, 2007, 03:10:37 »

Hi,

Before I begin I'd just like to say that PureMVC is simply amazing. For my first framework I have to say that it was very easy to pick up and dive into in a matter of days. Simple yet powerful. It has definitely made Flash development fun for me again and not some messy nightmare. And thanks to this framework, my first venture into the Flash development industry as an independent contractor has been a wonderful experience and it's only been my first month. Thank you very much Cliff for this beauty. I hope in to coming weeks, months, and years to give back to the community and contribute some of the stuff I'm able to build using this framework with all you developers out there.

Now onto my question.

I've just about completed my first Flash game using PureMVC and am now working on an online multiplayer Flash game using sockets. Throughout the development process something has been bugging me. I found myself placing most of my game logic inside a Proxy and I'm not so sure that that code is supposed to go in the Proxy. So for example, say a player's ship is hit by enemy fire. I'm going to want to decline the ships health amount by 1. The ships health is stored in a proxy called GameStateProxy which stores various info about the state of the player's ship (lives, health, ammo, etc). So the ships health starts at say, 10, and when it reaches 0 it's game over.

Now here's what takes place in the code. The Mediator sends the Notification(SHIP_HIT) to inform ShipHitCommand that the ship sprite has been hit. It is at that point, in ShipHitCommand's execute method, that I become unsure. Should I make a call to some method on GameStateProxy such as shipIsHit() which decrements the health value by one and checks if it has reached 0:
:
class GameStateProxy extends Proxy implements IProxy {
  private var state:Object;
  public function GameStateProxy() {
    state.health = 10;
  }
  //shipIsHit() called by ShitHitCommand
  public function shipIsHit() {
    health--;
    if (health <= 0) sendNotification(GFacade.GAME_OVER);
  }
  public function get health():Number {
    return state.health;
  }
  public function set health(val:Number):void {
    state.health = val;
  }
}


Or should ShipHitCommand handle that logic:

:
class ShipHitCommand extends SimpleCommand implements ICommand {
  override public function execute(note:INotification) {
     var gameStateProxy = facade.retrieve(GameStateProxy.NAME) as GameStateProxy;
     gameStateProxy.health--;
     if (gameStateProxy.health < 0) sendNotification(GAME_OVER);
  }
}

I reread the "Best Practices" doc and I get the feeling that no logic should go in the Proxy. The Proxy is there only to hold data and should not be reponsible for say, determining if it is game over, that should be the Command's responsibility.

-Andres
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: November 27, 2007, 06:46:08 »

Andres,

Glad to hear The framework is helping you out! And I certainly welcome your input to the community. Soon I'll have all the facilities in place to provide project space to anyone who wants to contribute.

As for the question you pose, I believe placing the logic in the Command is going to be most appropriate in your case.

In a more ordinary (business) app, when making these kinds of decisions, it comes down to whether we consider th logic in question to be 'domain logic' or 'business logic'.

That determination then can be made if you consider what would happen if you repackaged the entire Model region of the app for use with another app.

If you had a different app using this same Model, would the logic in question be the same? If so its probably domain logic and should live in the Model region.

If not it probably supports the unique use cases of this app and should live in the Controller region.

-=Cliff>
Logged
andres
Jr. Member
**
Posts: 14


View Profile Email
« Reply #2 on: November 28, 2007, 02:31:32 »

Interesting. I'll just leave the logic in the model for repackaging purposes then. But then that means that the Command is simply there solely for calling methods on the Proxy.

class ShipHitCommand {
  execute() {
     stateProxy.playerIsHit()
  }
}

So the Command is instantiated every time the player is hit simply to call a method on the Proxy. It seems like it would make more sense for me to call the Proxy method directly from the ShipMediator:

class ShipMediator {
  onHitTest(Ship, laser.x, laser,y) {
     stateProxy.playerIsHit();
  }
}

That way I skip the Command instantiating, but at the same time I introduce tight coupling between the Mediator and the Proxy. I understand that Commands are there in order to prevent coupling between the View and Model, but it seems like I'm going to have constant instantiating of Commands every time a player's ship is hit, or an enemy it hit, or an obstacle hits the player, etc. So I would have a Command for every possible event.

ShipHitCommand //calls the stateProxy.shipIsHit() method
EnemyHitCommand
ShipHitByRockCommand  //updates ship health in StateProxy
PlayerKeyPressedCommand //updates Ship position in StateProxy
QuitKeyPressedCommand //calls the stateProxy.quit() method
PauseKeyPressedCommand //calls the stateProxy.pause() method

The PureMVC demos on this site seem to all have only one or two commands used soley for instantiating the Proxy and Mediator classes. So I have no clue whether, for games, I need to use many Commands or if I should just call all Proxy methods from the Mediators, that way I skip the Command instantiation process thus eliminating overhead.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: November 28, 2007, 03:36:18 »

Feel free to call a Proxy method from a Mediator. In fact you'll notice most of the demos do that, and even go so far as to fetch and cache a local reference to frequently accessed proxies inside their constructors.

The primary reasons (aside from startup) to create a Command are if it houses some logic that might need to be triggered from multiple places, or to unencumber a Mediator which seeks a simpler role in the great scheme of things.

So, yeah. Axe the command and call the proxy from the Mediator. It is a coupling, but an accepted one within the MVC paradigm.

-=Cliff>
Logged
Pages: [1]
Print