如何使用玩家发布者数据授予对玩多个游戏的奖励

奖励通常涉及玩家数据以外的其他 系统,因此,为了简单起见,本示例演示授予虚拟货币。

要求

  • 一个 PlayFab 开发者帐户
  • 玩家必须使用相同的凭据登录两个 游戏。 一种方法是使用可恢复凭据,如登录基础知识和最佳实践教程中所述。 要向匿名帐户添加可恢复的登录,请参阅帐户关联教程。
  • 此示例要求您具备 CloudScript 应用知识:
    • 我们的示例演示基本数据安全性,以防止玩家作弊。 如果游戏使用的是自定义游戏服务器,您也可以在自定义游戏服务器上使用服务器 API。
  • 通过 PlayFab 触发的奖励需要使用相应的 PlayFab 功能。 PlayFab Rewards 可以采用虚拟货币清单项自定义玩家数据统计信息等形式。在 PlayFab 系统之外分发奖励是一个高级主题,本教程不介绍此主题。

我们还建议开发人员对从 CloudScript 发出的所有服务器 API 调用使用良好的错误处理。

每个游戏都向发布者数据报告登录名

登录后,每个游戏都需要进行报告。 为简单起见,我们的示例仅针对玩家玩的发布者的每一个其他游戏提供一份 奖励。

您可以任意拓展有关计数器、时间戳或其他机制的思路,以提供渐进或顺序奖励。

您的工作室中的每一个 游戏中都需要存在以下 CloudScript。

// CloudScript/Javascript

var PUBLISHER_USED_TITLES_KEY = "playedTitleIds";
handlers.TrackTitleUsage = function () {
    // Get the User Publisher Data for this player, and convert it into our expected format
    var getRequest = { Keys: [PUBLISHER_USED_TITLES_KEY], PlayFabId: currentPlayerId };
    var getResult = server.GetUserPublisherInternalData(getRequest);
    var playedTitlesList = JSON.parse(getResult.Data[PUBLISHER_USED_TITLES_KEY].Value); // format is arbitrary, but this example assumes Array<string>
    if (!playedTitlesList)
        playedTitlesList = [];
    // Check if we've played this title already
    var alreadyPlayed = false;
    for (var i = 0; i < playedTitlesList.length; i++)
        alreadyPlayed = alreadyPlayed || playedTitlesList[i] === script.titleId;
    if (alreadyPlayed)
        return; // Nothing to do
    // Update the list of played titles, and re-save
    playedTitlesList.push(script.titleId);
    var setRequest = { PlayFabId: currentPlayerId, Data: { PUBLISHER_USED_TITLES_KEY: JSON.stringify(playedTitlesList) } };
    server.UpdateUserPublisherInternalData(setRequest);
}

特别是,此示例说明如何使用:

每个游戏检查可兑换的奖励

跟踪要玩的游戏后,需要跟踪并授予奖励。 此 CloudScript 函数将根据玩家玩的其他游戏来检查和授予可用的奖励。

// CloudScript/Javascript

var PUBLISHER_REDEEMED_TITLES_KEY = "redeemedTitleIds";
var MY_CROSS_TITLE_REWARDS = { "AU": 10 };
handlers.CheckCrossTitleRewards = function () {
    // Get the publisher data concerning cross-title rewards for this player
    var getRequest = { Keys: [PUBLISHER_USED_TITLES_KEY, PUBLISHER_REDEEMED_TITLES_KEY], PlayFabId: currentPlayerId };
    var getResult = server.GetUserPublisherInternalData(getRequest);
    var redeemedTitleRewards = JSON.parse(getResult.Data[PUBLISHER_REDEEMED_TITLES_KEY].Value); // format is arbitrary, but this example assumes { [key: string]: Array<string> }
    if (!redeemedTitleRewards)
        redeemedTitleRewards = {};
    var playedTitlesList = JSON.parse(getResult.Data[PUBLISHER_USED_TITLES_KEY].Value); // format is arbitrary, but this example assumes Array<string>
    if (!playedTitlesList)
        playedTitlesList = [];

    // Determine which titles are un-redeemed
    var unredeemedTitleIds = [];
    for (var i = 0; i < playedTitlesList.length; i++) {
        if (!redeemedTitleRewards.hasOwnProperty(playedTitlesList[i]) && playedTitlesList[i] !== script.titleId)
            unredeemedTitleIds.push(playedTitlesList[i]);
    }
    if (unredeemedTitleIds.length === 0)
        return null; // Nothing to redeem

    // Give the cross title rewards
    var multiplier = unredeemedTitleIds.length;
    var actualRewards = {}; // MY_CROSS_TITLE_REWARDS is a global constant, so don't modify it or you'll mess up future calls
    // Please note that the number of API calls that may be made from CloudScript, as well as the total available processing time is limited,
    // and so the number of rewards should be as small as possible (only one VC, in this case)
    for (var eachKey in MY_CROSS_TITLE_REWARDS) {
        actualRewards[eachKey] = MY_CROSS_TITLE_REWARDS[eachKey] * multiplier;
        server.AddUserVirtualCurrency({ PlayFabId: currentPlayerId, VirtualCurrency: eachKey, Amount: MY_CROSS_TITLE_REWARDS[eachKey] }); // Can only add 1 VC at a time
    }

    // Save the Publisher data indicating rewards are claimed
    redeemedTitleRewards[script.titleId] = playedTitlesList;
    var setRequest = { PlayFabId: currentPlayerId, Data: { PUBLISHER_REDEEMED_TITLES_KEY: JSON.stringify(redeemedTitleRewards) } };
    server.UpdateUserPublisherInternalData(setRequest);

    // Tell the client the reward
    return actualRewards;
};

注意

此特定示例演示了 server.GetUserPublisherInternalData(请求多个键)、server.UpdateUserPublisherInternalData 和 server.AddUserVirtualCurrency 的用法。

代码块代表以下步骤:

总结

玩家发布者数据和玩家数据在结构上是相同的。

玩家数据应特定于游戏,而玩家发布者数据应 包含与您的所有游戏相关的信息。

另请参阅

简单游戏内交叉推广:奖励参与多个游戏的玩家。