Teams
Read more about the Teams system in Hiro here.
Core Functions
#
SetActivityCalculator
#
Specify a function to use when calculating team activity score.
1
2
3
4
5
6
7
8
9
10
| systems.GetTeamsSystem().SetActivityCalculator(ActivityCalculator)
func ActivityCalculator(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, team *Team) int64 {
// Used to resolve an activity score for a given team.
// Implementations may inspect the team members list to use individual activity scores as part of
// the calculation. Higher activity values should generally be used to indicate more active teams.
activityScore := 100
return int64(activityScore)
}
|
Create
#
Create a new team (i.e. Nakama group) with additional metadata which configures the team.
1
2
3
4
5
6
7
8
9
10
11
12
13
| request := &hiro.TeamCreateRequest{
Name: "MyTeam",
Desc: "My team description",
Open: true,
Icon: "iconUrl",
LangTag: "",
SetupMetadata: "<metadata>",
}
team, err := systems.GetTeamsSystem().Create(ctx, logger, nk, request)
if err != nil {
return err
}
|
List
#
List teams which the user can join.
1
2
3
4
5
6
7
8
9
10
| request := &hiro.TeamListRequest{
Cursor: "",
Location: "uk",
Limit: 10,
}
teams, err := systems.GetTeamsSystem().List(ctx, logger, nk, request)
if err != nil {
return err
}
|
Search
#
Search for teams based on given criteria.
1
2
3
4
5
6
7
8
9
10
| request := &hiro.TeamSearchRequest{
Input: "TeamName",
Limit: 10,
LangTag: "uk",
}
teams, err := systems.GetTeamsSystem().Search(ctx, db, logger, nk, request)
if err != nil {
return err
}
|
Update
#
Change one or more properties of the team.
1
2
3
4
5
6
7
8
9
10
11
| userId := "userId"
request := &hiro.TeamUpdateRequest{
Id: "teamId",
Name: "MyNewTeamName",
Open: true,
}
team, err := systems.GetTeamsSystem().Update(ctx, logger, nk, userId, request)
if err != nil {
return err
}
|
Get
#
Get one or more teams by their identifier.
1
2
3
4
5
6
| teamIds := []string{"teamId1", "teamId2"}
teams, err := systems.GetTeamsSystem().Get(ctx, db, logger, nk, teamIds)
if err != nil {
return err
}
|
UserTeamsList
#
Fetch user accounts and their associated teams.
1
2
3
4
5
6
7
8
| request := &hiro.UserTeamsListRequest{
UserIds: []string{"userId1", "userId2"},
}
list, err := systems.GetTeamsSystem().UserTeamsList(ctx, db, logger, nk, request)
if err != nil {
return err
}
|
WriteChatMessage
#
Send a message to the user’s team, even when they’re not connected on a realtime socket.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
request := &hiro.TeamWriteChatMessageRequest{
Id: "teamId",
Content: "Heya team!",
}
resp, err := systems.GetTeamsSystem().WriteChatMessage(ctx, logger, nk, userId, request)
if err != nil {
return err
}
|
UpdateMaxSize
#
Set a new maximum team size for the selected team.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
err := systems.GetTeamsSystem().UpdateMaxSize(ctx, logger, db, nk, userId, teamId, 5, true)
if err != nil {
return err
}
|
Economy
#
StoreList
#
Get the defined store items available to the team.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
storeItems, rewardModifiers, timestamp, err := systems.GetTeamsSystem().StoreList(ctx, logger, nk, userId, teamId)
if err != nil {
return err
}
|
StorePurchase
#
Validate a purchase and give the user ID the appropriate rewards.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
itemId := "itemId"
updatedWallet, updatedInventory, reward, err := systems.GetTeamsSystem().StorePurchase(ctx, logger, db, nk, userId, teamId, itemId)
if err != nil {
return err
}
|
SetOnPurchaseReward
#
Set a custom reward function which runs after a team store item’s reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnPurchaseReward(OnPurchaseReward)
func OnPurchaseReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.TeamEconomyConfigStoreItem, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
WalletGet
#
Fetch the wallet for a specified team.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
wallet, err := systems.GetTeamsSystem().WalletGet(ctx, logger, nk, userId, teamId)
if err != nil {
return err
}
|
WalletGrant
#
Grant currencies to the specified team’s wallet.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
teamId := "teamId"
currencies := map[string]int64{
"gold": 100,
}
wallet, err := systems.GetTeamsSystem().WalletGrant(ctx, logger, nk, userId, teamId, currencies)
if err != nil {
return err
}
|
Inventory
#
InventoryList
#
Return the items defined, as well as the computed item sets, for the team by ID.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
items, itemSets, err := systems.GetTeamsSystem().InventoryList(ctx, logger, nk, userId, teamId, "")
if err != nil {
return err
}
|
InventoryListInventoryItems
#
Return the items which are part of a team’s inventory by ID.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
inventory, err := systems.GetTeamsSystem().InventoryListInventoryItems(ctx, logger, nk, userId, teamId, "")
if err != nil {
return err
}
|
InventoryConsumeItems
#
Deduct the item(s) from the team’s inventory and run the consume reward for each one, if defined.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
teamId := "teamId"
itemIds := map[string]int64{
"healthPotion": 1,
}
updatedInventory, rewards, instanceRewards, err := systems.GetTeamsSystem().InventoryConsumeItems(ctx, logger, nk, userId, teamId, itemIds, nil, false)
if err != nil {
return err
}
|
InventoryGrantItems
#
Add the item(s) to a team’s inventory by ID, optionally setting properties on each granted item.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
teamId := "teamId"
itemIds := map[string]int64{
"healthPotion": 1,
}
updatedInventory, newItems, updatedItems, notGrantedItemIds, err := systems.GetTeamsSystem().InventoryGrantItems(ctx, logger, nk, userId, teamId, itemIds, nil, false)
if err != nil {
return err
}
|
InventoryUpdateItems
#
Update the properties which are stored on each item by instance ID for a team.
1
2
3
4
5
6
7
8
9
10
11
12
| userId := "userId"
teamId := "teamId"
instanceIds := map[string]*hiro.InventoryUpdateItemProperties{
"instanceId1": {
StringProperties: map[string]string{"durability": "80"},
},
}
updatedInventory, err := systems.GetTeamsSystem().InventoryUpdateItems(ctx, logger, nk, userId, teamId, instanceIds)
if err != nil {
return err
}
|
SetOnInventoryConsumeReward
#
Set a custom reward function which runs after a team inventory item consume reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnInventoryConsumeReward(OnInventoryConsumeReward)
func OnInventoryConsumeReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.InventoryConfigItem, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
SetInventoryConfigSource
#
Set a custom additional config lookup function for team inventory items.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetInventoryConfigSource(InventoryConfigSource)
func InventoryConfigSource(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, configID string) (*hiro.InventoryConfigItem, error) {
// Look up and return a config item not defined in the static configuration.
return nil, nil
}
|
Achievements
#
ClaimAchievements
#
Claim one or more achievements whose progress has completed by their IDs.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
achievementIds := []string{"achievementId1"}
achievements, repeatAchievements, err := systems.GetTeamsSystem().ClaimAchievements(ctx, logger, nk, userId, teamId, achievementIds, false)
if err != nil {
return err
}
|
GetAchievements
#
Return all achievements available to the user and their progress on them.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
achievements, repeatAchievements, err := systems.GetTeamsSystem().GetAchievements(ctx, logger, nk, userId, teamId)
if err != nil {
return err
}
|
UpdateAchievements
#
Update progress on one or more achievements by the same amount.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
teamId := "teamId"
achievementUpdates := map[string]int64{
"achievementId1": 1,
}
achievements, repeatAchievements, err := systems.GetTeamsSystem().UpdateAchievements(ctx, logger, nk, userId, teamId, achievementUpdates)
if err != nil {
return err
}
|
ResetAchievements
#
Reset one or more achievements by their IDs, deleting their progress from the storage entry.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
achievementIds := []string{"achievementId1"}
achievements, repeatAchievements, err := systems.GetTeamsSystem().ResetAchievements(ctx, logger, nk, userId, teamId, achievementIds)
if err != nil {
return err
}
|
SetOnAchievementReward
#
Set a custom reward function which runs after an achievement’s reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnAchievementReward(OnAchievementReward)
func OnAchievementReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.AchievementsConfigAchievement, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
SetOnSubAchievementReward
#
Set a custom reward function which runs after a sub-achievement’s reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnSubAchievementReward(OnSubAchievementReward)
func OnSubAchievementReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.AchievementsConfigSubAchievement, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
SetOnAchievementTotalReward
#
Set a custom reward function which runs after an achievement’s total reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnAchievementTotalReward(OnAchievementTotalReward)
func OnAchievementTotalReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.AchievementsConfigAchievement, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
Event Leaderboards
#
ListEventLeaderboard
#
Return the available event leaderboards for the team.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
eventLeaderboards, err := systems.GetTeamsSystem().ListEventLeaderboard(ctx, logger, nk, userId, teamId, true, nil)
if err != nil {
return err
}
|
GetEventLeaderboard
#
Return a specified event leaderboard’s cohort for the team.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().GetEventLeaderboard(ctx, logger, nk, userId, teamId, eventLeaderboardId)
if err != nil {
return err
}
|
RollEventLeaderboard
#
Place the team into a new cohort for the specified event leaderboard, if possible.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().RollEventLeaderboard(ctx, logger, nk, userId, teamId, eventLeaderboardId, nil, false, nil, nil)
if err != nil {
return err
}
|
UpdateEventLeaderboard
#
Update the team’s score in the specified event leaderboard, and return the team’s updated cohort information.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().UpdateEventLeaderboard(ctx, logger, db, nk, userId, teamId, eventLeaderboardId, 10, 0, nil, false)
if err != nil {
return err
}
|
ClaimEventLeaderboard
#
Claim the team’s reward for the given event leaderboard.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().ClaimEventLeaderboard(ctx, logger, nk, userId, teamId, eventLeaderboardId)
if err != nil {
return err
}
|
SetOnEventLeaderboardsReward
#
Set a custom reward function which runs after a team event leaderboard’s reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnEventLeaderboardsReward(OnEventLeaderboardsReward)
func OnEventLeaderboardsReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.EventLeaderboardsConfigLeaderboard, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
SetOnEventLeaderboardCohortSelection
#
Set a custom function that can replace the cohort or opponent selection feature of team event leaderboards.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnEventLeaderboardCohortSelection(OnEventLeaderboardCohortSelection)
func OnEventLeaderboardCohortSelection(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, storageIndex, eventID string, config *hiro.EventLeaderboardsConfigLeaderboard, userID, teamID string, tier int, matchmakerProperties map[string]interface{}) (cohortID string, cohortUserIDs []string, newCohort *hiro.EventLeaderboardCohortConfig, err error) {
// Select or create the cohort the team is placed into.
return "", nil, nil, nil
}
|
DebugFill
#
Fill the user’s current cohort with dummy teams for all remaining available slots.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().DebugFill(ctx, logger, nk, userId, teamId, eventLeaderboardId, 10)
if err != nil {
return err
}
|
DebugRandomScores
#
Assign random scores to the participants of the team’s current cohort, except to the team itself.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
eventLeaderboardId := "eventLeaderboardId"
eventLeaderboard, err := systems.GetTeamsSystem().DebugRandomScores(ctx, logger, nk, userId, teamId, eventLeaderboardId, 0, 100, 0, 0, nil)
if err != nil {
return err
}
|
Leaderboards
#
ListLeaderboard
#
Return the available team leaderboards.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
leaderboards, err := systems.GetTeamsSystem().ListLeaderboard(ctx, logger, nk, userId, teamId, nil)
if err != nil {
return err
}
|
GetLeaderboard
#
Return a specified team leaderboard.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
leaderboardId := "leaderboardId"
leaderboard, err := systems.GetTeamsSystem().GetLeaderboard(ctx, logger, nk, userId, teamId, leaderboardId)
if err != nil {
return err
}
|
ListLeaderboardScores
#
Return a list of team scores for a specified team leaderboard.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
leaderboardId := "leaderboardId"
scoreList, err := systems.GetTeamsSystem().ListLeaderboardScores(ctx, logger, nk, userId, teamId, leaderboardId, "", nil, 10, "", 0)
if err != nil {
return err
}
|
ListLeaderboardScoresAroundTeam
#
Return a list of team scores for a specified team leaderboard around the caller’s team.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
leaderboardId := "leaderboardId"
scoreList, err := systems.GetTeamsSystem().ListLeaderboardScoresAroundTeam(ctx, logger, nk, userId, teamId, leaderboardId, "", 10, "", 0)
if err != nil {
return err
}
|
UpdateLeaderboard
#
Submit a team member’s score contribution to the team’s record in the specified team leaderboard.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
leaderboardId := "leaderboardId"
leaderboard, err := systems.GetTeamsSystem().UpdateLeaderboard(ctx, logger, db, nk, userId, teamId, leaderboardId, 10, 0, nil, nil)
if err != nil {
return err
}
|
SetOnBeforeUpdateLeaderboardScore
#
Set a custom function which runs before a team leaderboard score is updated.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnBeforeUpdateLeaderboardScore(OnBeforeUpdateLeaderboardScore)
func OnBeforeUpdateLeaderboardScore(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, userID, teamID, leaderboardID string, score, subscore int64, metadata map[string]interface{}) (int64, int64, map[string]interface{}, error) {
// Modify the score, subscore, or metadata before the update is applied.
return score, subscore, metadata, nil
}
|
SetOnAfterUpdateLeaderboardScore
#
Set a custom function which runs after a team leaderboard score is updated.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnAfterUpdateLeaderboardScore(OnAfterUpdateLeaderboardScore)
func OnAfterUpdateLeaderboardScore(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, userID, teamID, leaderboardID string, score, subscore int64, metadata map[string]interface{}) (int64, int64, map[string]interface{}, error) {
// React to or adjust the score, subscore, or metadata after the update has been applied.
return score, subscore, metadata, nil
}
|
Reward Mailbox
#
RewardMailboxList
#
List the team reward mailbox, from most recent to oldest.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
mailboxList, err := systems.GetTeamsSystem().RewardMailboxList(ctx, logger, nk, userId, teamId, 10, "")
if err != nil {
return err
}
|
RewardMailboxClaim
#
Claim a reward and optionally remove it from the team mailbox.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
id := "mailboxEntryId"
mailboxEntry, err := systems.GetTeamsSystem().RewardMailboxClaim(ctx, logger, nk, userId, teamId, id, true)
if err != nil {
return err
}
|
RewardMailboxDelete
#
Delete a reward from the team mailbox, even if it isn’t yet claimed.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
ids := []string{"mailboxEntryId"}
err := systems.GetTeamsSystem().RewardMailboxDelete(ctx, logger, nk, userId, teamId, ids)
if err != nil {
return err
}
|
RewardMailboxGrant
#
Grant a reward to the team’s mailbox.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
reward := &hiro.Reward{}
mailboxEntry, err := systems.GetTeamsSystem().RewardMailboxGrant(ctx, logger, nk, userId, teamId, reward)
if err != nil {
return err
}
|
SetOnRewardMailboxClaimReward
#
Set a custom reward function which runs after a team mailbox reward is rolled during claiming.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnRewardMailboxClaimReward(OnRewardMailboxClaimReward)
func OnRewardMailboxClaimReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.RewardMailboxEntry, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
Stats
#
StatsList
#
Retrieve the full list of stats for the specified teams.
1
2
3
4
5
6
7
| userId := "userId"
teamIds := []string{"teamId1", "teamId2"}
stats, err := systems.GetTeamsSystem().StatsList(ctx, logger, nk, userId, teamIds)
if err != nil {
return err
}
|
StatsUpdate
#
Update public and private stats for the specified team.
1
2
3
4
5
6
7
8
9
10
| userId := "userId"
teamId := "teamId"
publicStats := []*hiro.StatUpdate{
{Name: "wins", Value: 1},
}
statList, err := systems.GetTeamsSystem().StatsUpdate(ctx, logger, nk, userId, teamId, publicStats, nil)
if err != nil {
return err
}
|
Gifts
#
GiftList
#
List available team gifts, including past gifts that still have valid rewards to claim.
1
2
3
4
5
6
7
| userId := "userId"
teamId := "teamId"
giftList, err := systems.GetTeamsSystem().GiftList(ctx, logger, nk, userId, teamId)
if err != nil {
return err
}
|
GiftContribute
#
Update the specified gift with a given contribution amount.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
giftId := "giftId"
ack, err := systems.GetTeamsSystem().GiftContribute(ctx, logger, nk, userId, teamId, giftId, 1)
if err != nil {
return err
}
|
GiftClaim
#
Claim all pending rewards for a particular gift.
1
2
3
4
5
6
7
8
| userId := "userId"
teamId := "teamId"
giftId := "giftId"
ack, err := systems.GetTeamsSystem().GiftClaim(ctx, logger, nk, userId, teamId, giftId, 0)
if err != nil {
return err
}
|
SetOnGiftContributeReward
#
Set a custom reward function which runs after a team gift contribution reward is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnGiftContributeReward(OnGiftContributeReward)
func OnGiftContributeReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.TeamGift, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|
SetOnGiftContributeCost
#
Set a custom reward function which runs after a team gift contribution cost is rolled.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnGiftContributeCost(OnGiftContributeCost)
func OnGiftContributeCost(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.TeamGift, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled cost before it's deducted from the team.
return reward, nil
}
|
SetOnGiftClaimReward
#
Set a custom reward function which runs after a team gift reward is rolled during claiming.
1
2
3
4
5
6
| systems.GetTeamsSystem().SetOnGiftClaimReward(OnGiftClaimReward)
func OnGiftClaimReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, teamID, sourceID string, source *hiro.TeamGift, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
// Modify or replace the rolled reward before it's granted to the team.
return reward, nil
}
|