Skip to content

Tutorials

Player Authentication

Login via Email (password-less)

  • Show the login UI to the player and prompt for their email address
  • Send the authentication request based on the example payload below
    • The player will receive a confirmation code at the provided email address
    • The code lifetime is 3 minutes
    • The player is not authenticated at this point
// Request type and method are always required to define the authentication action.
// Email is required when using it as the authentication method.
const payload = {
    email: "[email protected]",
    requestType: "login",
    method: "email",
};

Wortal.authenticateAsync(payload)
    .then(result => {
        // If successful the status will be "pending" as the action is
        // awaiting the confirmation code being sent.
        console.log("Auth result: " + result.status);

        if (result.status === "pending") {
            // Show the player a dialog to enter the confirmation code.
        } else {
            // Handle error status.
        }
    )}
    .catch(error => console.log(error));
  • Show a UI element that prompts the player to enter the confirmation code
  • Send the confirmation request with the code the player provided
    • Code should always be sent as string
const payload = {
    email: "[email protected]",
    code: "1234",
    requestType: "login",
    method: "email",
};

Wortal.authenticateAsync(payload)
    .then(result => {
        // If successful the status will be "success"
        console.log("Auth result: " + result.status);

        if (result.status === "success") {
            // Now the player is logged in. Refresh UI, fetch player data, etc.
        } else {
            // Handle error status.
        }
    )}
    .catch(error => console.log(error));

Login via Phone Number (password-less)

  • Show the login UI to the player and prompt for their phone number
  • Send the authentication request based on the example payload below - The player will receive a confirmation code via SMS at the provided number - The phone number MUST begin with '+' and the country code. - The phone number may contain spaces, hyphens and parentheses - Valid format examples: - +1234567890 - +1 (234) 567-890 - +12-345-678-90 - Invalid format examples: - 1234567890 (No '+' before country code) - +123abc456 (Letters not allowed) - The code lifetime is 3 minutes - The player is not authenticated at this point
// Request type and method are always required to define the authentication action.
// Phone is required when using it as the authentication method.
const payload = {
    phone: "+1234567890",
    requestType: "login",
    method: "phone",
};

Wortal.authenticateAsync(payload)
    .then(result => {
        // If successful the status will be "pending" as the action is
        // awaiting the confirmation code being sent.
        console.log("Auth result: " + result.status);

        if (result.status === "pending") {
            // Show the player a dialog to enter the confirmation code.
        } else {
            // Handle error status.
        }
    )}
    .catch(error => console.log(error));
  • Show a UI element that prompts the player to enter the confirmation code
  • Send the confirmation request with the code the player provided - Code should always be sent as string
const payload = {
    phone: "+1234567890",
    code: "1234",
    requestType: "login",
    method: "phone",
};

Wortal.authenticateAsync(payload)
    .then(result => {
        // If successful the status will be "success"
        console.log("Auth result: " + result.status);

        if (result.status === "success") {
            // Now the player is logged in. Refresh UI, fetch player data, etc.
        } else {
            // Handle error status.
        }
    )}
    .catch(error => console.log(error));

Rewarded Ads

Rewarded ads are a great way to monetize your game. They allow players to watch an ad in exchange for a reward, such as in-game currency or an extra life. This tutorial will show you how to integrate rewarded ads into your game.

Examples

In the following examples, we'll show you how to reward the player with bonus currency when they watch an ad. Three common examples we'll explore are:

  1. Using a multiplier to increase earnings at the end of a level
  2. Using rewarded ads to give the player a second chance when they lose a level
  3. Using rewarded ads in an IAP shop to provide a non-paying alternative to purchasing in-game currency, which can help increase IAP conversion.

Multiplier

// Player has the finished level and is shown the results screen with the option to watch an ad for bonus currency.
const levelEarnings = 100;
const rewardMultiplier = 3;
function onRewardButtonClicked() {
    Wortal.ads.showRewarded("Level 1 Finish",
        () => {
            // beforeAd
            pauseGame();
        },
        () => {
            // afterAd
            resumeGame();
        },
        () => {
            // adDismissed
            addCurrency(levelEarnings);
        },
        () => {
            // adViewed
            addCurrency(levelEarnings * rewardMultiplier);
        },
        () => {
            // noFill
            addCurrency(levelEarnings);
        });
}

Second Chance

// Player has lost the level and is shown the results screen with the option to watch an ad for a second chance.
function onRewardButtonClicked() {
    Wortal.ads.showRewarded("Level 2 Retry",
        () => {
            // beforeAd
            pauseGame();
        },
        () => {
            // afterAd
            resumeGame();
        },
        () => {
            // adDismissed
            endGame();
        },
        () => {
            // adViewed
            continueGame();
        },
        () => {
            // noFill
            endGame();
        });
}

IAP Shop

// Player has opened the IAP shop. They can select an item that costs currency or watch an ad for bonus currency.
function onRewardButtonClicked() {
    Wortal.ads.showRewarded("IAP Shop",
        () => {
            // beforeAd
            pauseAudio();
        },
        () => {
            // afterAd
            resumeAudio();
        },
        () => {
            // adDismissed
            // Player doesn't get bonus currency as they didn't finish the ad.
            // You can display a UI popup explaining this to the player.
            noRewardPopup.show();
        },
        () => {
            // adViewed
            addCurrency()
        },
        () => {
            // noFill
            // Player doesn't get bonus currency as no ad was available.
            // You can display a UI popup explaining this to the player.
            noAdAvailablePopup.show();
        });
}

Handling No Fills

Gameplay should not break or become stuck due to an ad call failing to return an ad instance, as this is an unfortunate, but expected situation. If a gameplay feature is ad-gated behind a rewarded ad then it's important to properly handle the case where no ads are available to avoid the game becoming stuck or other issues such as UI buttons appearing to not work.

We recommend two different ways to handle this scenario: 1. Offer the player an opportunity to earn the reward in a different way, such as via a social share or invite (if supported on the current platform) 2. Inform the player that no ad is currently available and suggest that they try again later.

We've successfully implemented option #1 in our titles and recommend that where possible to help drive player engagement.

Ad calls that don't get filled or encounter errors will return the noFill callback. This is the callback you will want to use to implement the logic to handle this scenario.

Example Social Share Alternative

// Player has the finished level and is shown the results screen with the option to watch an ad for bonus currency.
const levelEarnings = 100;
const rewardMultiplier = 3;
function onRewardButtonClicked() {
    Wortal.ads.showRewarded("Level 1 Finish",
        () => {
            // beforeAd
            pauseGame();
        },
        () => {
            // afterAd
            resumeGame();
        },
        () => {
            // adDismissed
            addCurrency(levelEarnings);
        },
        () => {
            // adViewed
            addCurrency(levelEarnings * rewardMultiplier);
        },
        () => {
            // noFill
            // No ad was available, so we'll offer the player the option to share the game instead.
            shareAlternativePopup.show();
            if (shareAlternativePopup.result === "share") {
                // Player chose to share the game, so we'll reward them for doing so.
                Wortal.context.shareAsync({
                    intent: "SHARE",
                    payload: {
                        text: "I just finished level 1!",
                        image: "https://example.com/level1.png",
                        data: {
                            level: 1,
                            // Friends that open the game via the share link will receive a bonus.
                            // This can be accessed via Wortal.session.getEntryPointData().
                            shareBonus: 100
                        }
                    }
                }).then(() => {
                    // Share was successful, so we'll reward the player.
                    addCurrency(levelEarnings * rewardMultiplier);
                }).catch((error) => {
                    // Share failed, so we'll just reward the player for finishing the level.
                    addCurrency(levelEarnings);
                });
            } else {
                // Player chose not to share the game, so we'll just reward them for finishing the level.
                addCurrency(levelEarnings);
            }
        });
}