Energy

Read more about the Energy system in Hiro here.

Functions #

Get #

Get all energies defined and the values a user currently owns by ID.

1
2
3
4
5
6
userId := "userId"

energies, err := systems.GetEnergySystem().Get(ctx, logger, nk, userId)
if err != nil {
  return err
}

Spend #

Deduct the given amounts from each energy for a user by ID.

1
2
3
4
5
6
7
userId := "userId"
amounts := map[string]int32{"hearts": 1, "stamina": 3}

energies, reward, err := systems.GetEnergySystem().Spend(ctx, logger, nk, userId, amounts)
if err != nil {
  return err
}

SpendWithRefillStartTime #

Deduct the given amounts from each energy and set custom refill start times for a user by ID.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
userId := "userId"
spends := map[string]*hiro.EnergySpendWithTime{
    "hearts": {Amount: 1, RefillStartTime: time.Now().Add(-5 * time.Minute).Unix()},
    "stamina": {Amount: 3, RefillStartTime: time.Now().Unix()},
}

energies, reward, err := systems.GetEnergySystem().SpendWithRefillStartTime(ctx, logger, nk, userId, spends)
if err != nil {
    return err
}

BatchSpend #

Deduct the given amounts from each energy for multiple users in a single atomic transaction. Either all users spend successfully or none do. usersAmounts is a map of user IDs to energy amounts. Each user can spend from one or more energy types in the same call.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
usersAmounts := map[string]map[string]int32{
    "userId1": {"hearts": 1, "stamina": 3},
    "userId2": {"hearts": 2},
    "userId3": {"stamina": 5},
}

userEnergies, userRewards, err := systems.GetEnergySystem().BatchSpend(ctx, logger, nk, usersAmounts)
if err != nil {
    return err
}

If any user has insufficient energy, the entire transaction fails and no energy is deducted for any user. Duplicate user IDs in usersAmounts are deduplicated automatically.

The function returns:

  • userEnergies: a map of user ID to energy ID to current Energy state after deduction
  • userRewards: a map of user ID to the aggregated Reward earned across all energy spends for that user

Grant #

Add the given amounts to each energy (while applying any energy modifiers) for a user by ID.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
userId := "userId"
amounts := map[string]int32{"hearts": 1, "stamina": 3}
modifiers := []*hiro.RewardEnergyModifier{{
  Id:          "myModifier",
  Operator:    "multiplier",
  Value:       2,
  DurationSec: 86400,
  Weight:      -1,
}}

energies, err := systems.GetEnergySystem().Grant(ctx, logger, nk, userId, amounts, modifiers)
if err != nil {
  return err
}

Hooks #

SetOnSpendReward #

Set a custom reward function which will run after an energy reward’s value has been rolled.

1
2
3
4
5
6
systems.GetEnergySystem().SetOnSpendReward(OnSpendReward)

func OnSpendReward(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule, userID, sourceID string, source *hiro.EnergyConfigEnergy, rewardConfig *hiro.EconomyConfigReward, reward *hiro.Reward) (*hiro.Reward, error) {
	// Modify reward or take additional actions.
	return reward, nil
}