# Energy

**URL:** https://heroiclabs.com/docs/hiro/unity/energy/
**Keywords:** energy, hiro
**Categories:** hiro, unity, energy

---


# Energy

Read more about the Energies system in Hiro [here](../../concepts/energy/).

## Initializing the energies system

The energies system relies on the [Nakama System](../getting-started/nakama-system) and an `ILogger`, both must be passed in as dependencies via the constructor.

```csharp
var energiesSystem = new EnergiesSystem(logger, nakamaSystem);
systems.Add(energiesSystem);
```

## Subscribing to changes in the energy system

You can listen for changes in the energy system so that you can respond appropriately, such as updating the UI, by implementing the `IObserver` pattern, or use the `SystemObserver<T>` type which handles it for you.

```csharp
var disposer = SystemObserver<EnergiesSystem>.Create(energiesSystem, system => {
    Instance.Logger.Info($"System updated.");

    // Update UI elements etc as necessary here...
});
```

## Refreshing the energy system

To ensure the energy system has the latest information from Nakama you can refresh it.

```csharp
await energiesSystem.RefreshAsync();
```

## Listing available energy

You can list the available energies for a user.

```csharp
foreach (var energyKvp in energiesSystem.Energies)
{
    var name = energyKvp.Key;
    var energy = energyKvp.Value;

    Debug.Log($"Energy {name} ({energy.Current}/{energy.Max})");
    Debug.Log($"Next refill in {(energy.NextRefillTimeSec - energy.CurrentTimeSec) / 1000}s");
}
```

## Spending energy

You can spend energy as a user, either as a single energy at a time or as multiple at once.

```csharp
// Spend a single energy
await energiesSystem.SpendEnergyAsync("lives", 1);

// Spend multiple energies
await energiesSystem.SpendEnergyAsync(new Dictionary<string, int>
{
    { "lives", 1 },
    { "hearts", 5 }
});
```

## Spending energy with a custom refill start time

Spend energy and specify when the refill timer should start. Pass a map of `EnergySpendWithTime` to set a different start time per energy.

```csharp
var spends = new Dictionary<string, EnergySpendWithTime>
{
    { "hearts", new EnergySpendWithTime { Amount = 1, RefillStartTimeDecoded = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() } },
    { "stamina", new EnergySpendWithTime { Amount = 3, RefillStartTimeDecoded = DateTimeOffset.UtcNow.AddMinutes(-5).ToUnixTimeSeconds().ToString() } }
};

await energiesSystem.SpendEnergyWithRefillStartTimeAsync(spends);
```

To apply the same refill start time to all energies at once, pass a spend map and a shared Unix timestamp.

```csharp
var energies = new Dictionary<string, int>
{
    { "hearts", 1 },
    { "stamina", 3 }
};
var refillStartTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

await energiesSystem.SpendEnergyWithRefillStartTimeAsync(energies, refillStartTime);
```


## Granting energy

While energy can be granted as part of a reward, you can also grant it directly.

```csharp
await energiesSystem.GrantAsync(new Dictionary<string, int>
{
    { "lives", 1 },
    { "hearts", 5 }
});
```
## Additional information

- [Mage Mayhem sample project](../../../../sample-projects/games/mage-mayhem)
