void SwitchGame(int dir)
    {
        HFTMessageSwitchGame data = new HFTMessageSwitchGame();

        data.pos   = transform.position;
        data.vel   = m_rigidbody2d.velocity;
        data.name  = m_playerName;
        data.color = m_color;
        data.dir   = m_direction;

        // Look up the id of the game we are in. Something like "level3"
        string gameId = MultiMachineLevelSettings.settings.playerSpawner.server.Id;
        // Extract the number part
        int numNdx  = gameId.IndexOfAny("0123456789".ToCharArray());
        int gameNum = System.Convert.ToInt32(gameId.Substring(numNdx));

        // Increment or Decrement the number wraping at the ends
        gameNum = (gameNum + MultiMachineLevelSettings.settings.numGames + dir) % MultiMachineLevelSettings.settings.numGames;

        // Build the ID of the game we want to switch to
        gameId = gameId.Substring(0, numNdx) + gameNum;

        // Send this player to that game.
        // Note: No more messages will be received or sent to this player.
        m_netPlayer.SwitchGame(gameId, data);
    }
    // Called when player connects with their phone
    void InitializeNetPlayer(SpawnInfo spawnInfo)
    {
        Init();

        m_netPlayer = spawnInfo.netPlayer;
        m_netPlayer.OnDisconnect += Remove;

        // Setup events for the different messages.
        m_netPlayer.RegisterCmdHandler <MessageMove>("move", OnMove);
        m_netPlayer.RegisterCmdHandler <MessageJump>("jump", OnJump);

        m_playerNameManager = new HFTPlayerNameManager(m_netPlayer);
        m_playerNameManager.OnNameChange += HandleNameChange;

        // We always get a `data` so check if it has one key from our expected message
        Dictionary <string, object> dict = spawnInfo.data as Dictionary <string, object>;

        if (dict != null && dict.ContainsKey("dir"))
        {
            // This player was transferred from another game.

            // Turn the data back into our structure
            DeJson.Deserializer  deserializer = new DeJson.Deserializer();
            HFTMessageSwitchGame data         = deserializer.Deserialize <HFTMessageSwitchGame>(spawnInfo.data);

            // Choose a starting position based on the old position
            float x = (data.pos.x < MultiMachineLevelSettings.settings.leftEdgeOfLevel.position.x)
                ? MultiMachineLevelSettings.settings.rightEdgeOfLevel.position.x - 1 : MultiMachineLevelSettings.settings.leftEdgeOfLevel.position.x + 1;
            transform.localPosition = new Vector3(x, data.pos.y, 0f);

            // Set the initial velocity
            m_rigidbody2d.velocity = data.vel;

            // And the direction
            m_direction = data.dir;

            SetName(data.name);
            SetColor(data.color);
        }
        else
        {
            // This player just joined.
            MoveToRandomSpawnPoint();
            SetName(m_playerNameManager.Name);
            float           hue   = Random.value;
            float           sat   = (float)Random.Range(0, 3) * -0.25f;
            MessageSetColor color = new MessageSetColor(
                hue,
                sat,
                0.0f,
                m_material.GetFloat("_HSVRangeMin"),
                m_material.GetFloat("_HSVRangeMax"));
            SetColor(color);

            // Send it to the phone
            m_netPlayer.SendCmd("setColor", color);
        }
    }