Flox Password Login & Conflict Handling

Daniel Sperl on November 28, 2014

Hello guys! It's been a while since we last updated the Flox client library, so it was high time for an update! This time, we're adding two features that have been requested several times in the forum. I think we found very elegant solutions for those areas — read on to learn all about it!

Login with Email and Password

Our existing "email-login" is very convenient for casual games and works great on mobile devices. Users don't have to remember any password and just have to click on a link in an e-mail once per device.

However, for a web-based game, it's not so great: every time players switch the browser or lose their Flash-cookies, the e-mail confirmation has to be sent again. For this kind of game, the new "Email-Password" login should be a much better fit. It works like this:

  • To sign up, the player picks an e-mail address and a password. This triggers a confirmation e-mail.
  • As soon as the address is confirmed, she can login on any device with the chosen password. No more mails will be sent.
  • If she forgets her password, she can request a reset. That will trigger a new e-mail which allows her to choose a new password.

Below, you'll find sample code for those steps. Note that both sign-up and login are handled via the new method Player.loginWithEmailAndPassword(). The third parameter (loginOnly) is used to differentiate between sign-up and login.

// Register a new player:
Player.loginWithEmailAndPassword("me@there.com", "my-password", false,
    function onComplete(currentPlayer:Player):void
    {
       trace("This player is apparently already registered. She's now logged in.");
    },
    function onError(error:String, httpStatus:int, confirmationMailSent:Boolean):void
    {
        if (confirmationMailSent)
            trace("The user was sent a confirmation mail. She must confirm the " +
                  "message before being able to log in.");
        else
            trace("This e-mail address is already taken.");
    });

// Login an existing player:
Player.loginWithEmailAndPassword("me@there.com", "my-password", true,
    function onComplete(currentPlayer:Player):void
    {
       trace("Player logged in: " + currentPlayer);
    },
    function onError(error:String, httpStatus:int):void
    {
        if (httpStatus == HttpStatus.FORBIDDEN)
            trace("Unknown e-mail or wrong password");
        else
            trace("Error during login:", httpStatus, error);
    });

// Reset password:
Player.resetEmailPassword("me@there.com",
    function onComplete():void
    {
       trace("An e-mail that initiates a password reset has been sent.");
    },
    function onError(error:String, httpStatus:int):void
    {
        trace("Could not reset password:", httpStatus, error);
    });

All in all, you'll see that the code is very similar to the existing "e-mail"-login; I'm sure you'll be able to add that logic to your game in no time.

Conflict Handling for Entities

Our entity system is very robust and flexible — I hope you all agree with that! Most of the time, it just works, and you don't have to take special care to keep everything in sync.

However, there are a few edge cases where problems may pop up, e.g. when an entity has been modified on several devices simultaneously, or if a user was in offline-mode for a while. In those situations, it could happen that an entity is overwritten by one of it's older versions — and in the past, it was very hard to prevent that.

Here's an example. Let's say you've got an entity called SaveGame which stores the player's current level. A player levels up on both her iPhone and iPad. When one of the devices goes offline for a while, the player continues on the other one. Now, when the offline device finally connects to the internet again, it will override the level with an old value!

With the latest version of Flox, you can take the necessary precautions so that this does not happen. Flox will notify you of such a conflict via the new onConflict() method. It is called automatically by Flox when it detects — during a save operation — that the entity has been modified since you last loaded it. You can then inspect both versions of the entity (the one on the server and your local version) and update its properties as you see fit.

public class SaveGame extends Entity
{
    private var _level:int;

    override protected function onConflict(remoteEntity:Entity):void
    {
        var that:SaveGame = remoteEntity as SaveGame;
        this.level = Math.max(this.level, that.level);
    }

    public function get level():int { return _level; }
    public function set level(value:int):void { _level = value; }
}

Quite simple, right? You just override onConflict() and update the local entity (this) so that it contains the higher value. That value is then stored on the Flox servers.

All of that is totally optional, of course. If you don't override that method, the behavior is just like before: the latest call to save() will always win, overwriting any previous content.

That's it!

I hope you like those two little additions to the Flox tool belt! As always, you can find the latest version of the client library (it's version 1.3) in the "SDK" section of your game panel, directly in the Flox online interface.

If you've got any questions or remarks, don't be shy and leave a comment below — we're looking forward to any feedback!