3 Replies Latest reply on Apr 13, 2010 8:53 PM by clonberger

    dataservices and game scoring persistence?

    clonberger

      Hey guys, I may be drastically overthinking this and need a quick reality check.

       

      I'm using flex data servies to communicate to a server running PHP.

       

      I have different actions within the game that can happen as a result of the user doing something inside the flex app, or things being done to them while the swf is not loaded (php, cron, etc).

       

      All I want to do is simply update the user with the changes since their last log in.

       

      ex:

       

      "You earned 3000exp, made $232, ran out of ammo, found a furbie, and gained 5 new friends since your last login!"

       

      Pretty basic right?

       

      The problem I'm having is how to determine what has changed between logins.

       

      Currently i'm looking at creating a php/mysql-based event system that records actions as they happen (either due to a online action, or an offline action), and then have a column in the table "displayedToUser" which is a basic bool that is updated when the user logs back in and the updates are displayed.  When the user logs back in, the intersticial screen pulls records that have not been displayed, and voila.  Basically messaging.

       

      I've also contemplated sharedObjects to store the pertinent user data but then this breaks when they hop to a different browser (not a train wreck).

       

      Also, I'm having a hard time conceptualizing how to abstract the action types as they have their own pertinent data...

       

      ie:  a new friend would have a friendId, a new award may have an awardId, etc.

       

      I started looking at game engines hopeful for this type of support... found push button engine, flixel, flashpunk, etc, etc.. but they all seem overkill for something so simple (i'm not doing any kind of 'game play' front end isometric or otherwise -- yet).

       

      Is there a more simplistic elegant way to do this or am I on the right path?

       

      Thanks a lot for your insights

        • 1. Re: dataservices and game scoring persistence?
          JeffryHouser Level 4

          Wow.. Lots of stuff to cover.  I don't think any of it is Flex Specific; more architecture oriented.  But, I'll give it a shot:

           


          When the user logs out, or when the user's session time outs; time stamp their account some how.  Let the account remain inactive.  Next time they sign in; run a script to figure out what all should have happened while they were gone.  If users affect each other, you can queue those up in the database somehow.  Otherwise you probably have some algorithms along the lines of:

           

          "Every 24 hours you earn 1,000 experience points; and since you didn't log in for three days, you get 3,000 experience points."

           

          or

           

          "You have four farms and two guns; therefore were able to kill one wolf with each gun on the farm that was protected making $200 per wolf, but the other two unprotected farms lost six sheep each, losing 700 each, so your net total is a loss of $1,000"

           

          or whatever.

           

          To implement this stuff; I would use the command design pattern for each special action.  The command design pattern is class which has an "Execute" method.  You can pass in a value object of relevant data.

           

          So, for example; every 'command' accepts a UserID or a User Object.  When the user signs in, you make a database call (they have four farms); and then you call the "farm.execute" method passing in their user object.  The farm object pings the database to find out that one farm has 2 sheep; and that means since the last login (3 days) the user generated four wool coats which can be sold for ....

           

           

          Having a "DisplayedToUser" table is fine; but I would only use that for archive purposes.  What you really care about is what happened between the last sign out and this login.  Create "Entries" for that stuff when the user logins in; store it in the 'displayedToUser" table (archive) and show it to the user.

           

          If there is a social aspect to the game; you can queue up said requests based on the userID.  They just don't take affect until the user logs in and you run that "Execute" command.

           

          I hope I'm not massacring whatever cool stuff is in your game by making up scenarios.  I hope this helps; but it is more of a brainstorm than a specific solution for you.

          • 2. Re: dataservices and game scoring persistence?
            clonberger Level 1

            Jeffry,

             

            AWESOME.  I really appreciate the thurough response, it was very helpful.

             

            After spending the afternoon researching and trying to wrap my mind around the Command behavioral pattern I'm still a little confused.  If you're up to it I'd love to run a few things by you to help clarify and fill in the gaps.... hopefully it will help others also.

             

            Some overarching goals/clarifications (apologies, erroring on the side of too much info):

             

            1. I'm attempting to build this as implicitly as possible so I can easily reuse it (quickly/easily) for future games
              1. this one might have a farm, sheep, and wolves
              2. the next one might have cars, and pedestrians
              3. Would like to just setup the front end, connect it to the backend, fire up phpmyadmin and edit the values/names/images/scoring/etc of the actions/awards tables
            2. I want to use the same code base and define the scoring/award logic within the database records if possible (no customization pushes needed)
              1. action NAME generates X score Y currency, etc
              2. award NAME received when score X action Y level Z
            3. Some events will need more logic than just scoring (which is why command pattern is so effective here i'm guessing?)
              1. ex: check to see if new friends are playing would require me to query fb (or whatever social platform), compare to existing players table in the db, and then calculate score/currency/items/awards/leves/etc earned for successfully inviting more players

             

            Basic plan:

             

            1. Feed active session actions into the Action Command pattern
            2. On every request (?) iterate through every ActionType feeding them individually to the Action Command pattern to see if anything has changed behind the scenes (ie: one of their friends joined the game and responded to an invite, their fan status for a page changed, a friend sent a msg, etc)  -- maybe this is more suitable for remoting? (something i know very little about)
            3. The Action Command pattern dynamically loads the logic to be used from the comand class, based on the action name supplied for the particular userID
            4. Command class performs needed opperations, returns earned awards (loose term describing action yield)/score/currency/etc
            5. Return is pushed back to the client and displayed

             

            Command pattern assumptions:

             

            1. I'm using a Command Pattern to add logic to the actual object that can be fired dynamically per Action type
            2. I should implement the pattern via php on the server (to prevent users from manipulating the swf and "adjusting" their scores), and also to abstract if I later decide to add a non flex frontend (objective c iphone, html, etc)
            3. Every action type needs to have its own handler in the Command class itself

             

             

            Tried to flesh out a basic Command pattern and ended up really confused on if i'm going about it the wrong way, seems like a really confusing switch statement?  :-)

             

             

            <?php

            class UserCommandee {
                private $userID;
                private $lastLogin;
                private $newScore;
                private $newCurrency;
                private $newAwardsArray;
                private $currency;
                private $score;
                private $awardsArray;

                function __construct($userID_in) {
                    $this->setUser($userID_in);
                    $this->setActionName($actionName_in);
                    $this->setLastLogin();
                }
                function getUser() {
                    return $this->userID;
                }
                function setUser($userID_in) {
                    $this->userID = $userID_in;
                }
              

                function setLastLogin(){
                    
                      //query user table to find out last timestamp
                      $this->lastLogin = returnedTimeStamp;

                }

                 function getLastLogin(){
                      return $this->lastLogin;
                 }

                 function newUsers() {

                      //hit fb API to see friends now in app
                      //query friends table against $this->userID to see who's new
                      //calculate and set additional awards, score, and currency based on # of new users
                 }

                 function farmed() {

                      //checks 'farmed' action type
                      //pulls # of farms from users database
                       //calculate and set additional awards, score, and currency based on time since lastLogin


                 }


            }

            abstract class ActionCommand {
                protected $actionCommandee;
                function __construct($actionCommandee_in) {
                    $this->actionCommandee = $actionCommandee_in;
                }
                abstract function execute();
            }



            class FriendInvitedCommand extends ActionCommand {
                function execute() {
                    $this->UserCommandee->newUsers();
                }
            }

            class FarmedCommand extends ActionCommand {
                function execute() {
                    $this->UserCommandee->farmed();
                }
            }


              function callCommand(ActionCommand $userCommand_in) {
                $actionCommand_in->execute();
              }


            //test it out

             

            $user = new UserCommandee($userID);

             

            foreach event type in db table:

                 $newAction = new call_user_func($row[actionName], $user); //dynamically call the class for the particular action?


            //After writing this I'm wondering if I misunderstood your previous statement and I should create a separate command pattern for each action type?

             

            • 3. Re: dataservices and game scoring persistence?
              clonberger Level 1

              Also, the base from what I tried to flesh out was pulled from a variety of tutorials such as:

               

              http://sourcemaking.com/design_patterns/command/php

               

              also a great 2 part series I found, and in AS3:

               

              Originally Posted by CJ Cat

               

              Sometimes developing a large game project can end up with messy code. Thus, it's necessary to manage classes in a systematic way, with maintainability in mind.

              Recently I've come up with an idea of a command framework which makes use of the Command Pattern.
              And I decided to write a tutorial on its applications.

              In this tutorial I demonstrated how to create a minimalistic command framework and scene manage framework. I think it's very useful for large game projects, or even general rich application projects. It helps you manage a project as modular pieces, making the responsibility of each object simple and clean.

              Part 1
              http://active.tutsplus.com/tutorials...s-part-1-of-2/

              Part 2
              http://active.tutsplus.com/tutorials...s-part-2-of-2/

              I hope you guys like it.