# Base

**URL:** https://heroiclabs.com/docs/hiro/unity/base/
**Summary:** A group of features that are common to all games.
**Keywords:** base, hiro
**Categories:** hiro, unity, base

---


# Base

Read more about the Base system in Hiro [here](../../concepts/base/).

## In-App Purchases

You can use the pre-packaged `UnityPurchasingSystem` to manage in-app purchases.

### Initialize the UnityPurchasingSystem

The UnityPurchasingSystem relies on the [Economy System](../../concepts/economy/) and an `ILogger`, both must be passed in as dependencies via the constructor.

```csharp
var purchasingSystem = new UnityPurchasingSystem(logger, economySystem);
systems.Add(purchasingSystem);
```

### Adding products

You can manually add products which are not defined in the Economy system. These product definitions could come from the Unity IAP definitions.

```csharp
var productDefinitions = new List<ProductDefinition>
{
    new ProductDefinition("<productId>", ProductType.Consumable)
};

await purchasingSystem.AddProductsAsync(productDefinitions);
```

### Purchasing a store item

You can purchase a store item defined in the Economy system.

```csharp
// Get a store item
var storeItem = economySystem.StoreItems.First();

var purchaseEventArgs = await purchasingSystem.BuyProductAsync(storeItem);
Debug.Log($"Receipt: {purchaseEventArgs.purchasedProduct.receipt}");
```

You can also purchase an item by product ID.

```csharp
var purchaseEventArgs = await purchasingSystem.BuyProductByIdAsync("<productId>");
```

### Processing a purchase

You can process a purchase.

```csharp
var processingResult = purchasingSystem.ProcessPurchase(purchaseEventArgs);
Debug.Log($"Processing result: {processingResult}");
```

### Restoring purchases

You can restore purchases.

```csharp
await purchasingSystem.RestorePurchasesAsync();
```

### Getting localized product price

You can get the localized product price.

```csharp
var price = purchasingSystem.GetLocalizedProductPrice(storeItem);
Debug.Log($"{storeItem.Name} price: {price}");
```

You can also get a localized product price by product ID.

```csharp
var price = await purchasingSystem.GetLocalizedProductPriceById("<productId>");
```

## App rating

You can let the user rate your application using the `NakamaSystem`'s `RateAppAsync` function which will trigger a feedback email to whichever email address is configured on the server.

```csharp
var score = 5;
var message = "I love this game!";
await nakamaSystem.RateAppAsync(score, message);
```

## Push notifications

### Initialize the UnityMobileNotificationsSystem

The UnityMobileNotificationsSystem takes an `ILogger` that must be passed in as a dependency via the constructor..

```csharp
var mobileNotificationsSystem = new UnityMobileNotificationsSystem(logger);
systems.Add(mobileNotificationsSystem);
```

### Observing systems

Some Hiro systems can be observed by the `UnityMobileNotificationsSystem` to automatically schedule relevant notifications.

You can customise the notification titles and messages if you would like, as seen below:

#### Achievements System

```csharp
var achievementsSystem = this.GetSystem<AchievementsSystem>();
var unityMobileNotificationsSystem = this.GetSystem<UnityMobileNotificationsSystem>();
var messages = new AchievementsNotificationMessages
{
    RepeatAvailableFunc = achievement => new NotificationMessage
    {
        Title = "Repeat achievement available!",
        Body = $"The repeat achievement '{achievement.Name}' is available."
    }
};
unityMobileNotificationsSystem.ObserveSystem(achievementsSystem, messages);
```

#### Unlockables System

```csharp
var unlockablesSystem = this.GetSystem<UnlockablesSystem>();
var unityMobileNotificationsSystem = this.GetSystem<UnityMobileNotificationsSystem>();
var messages = new UnlockablesNotificationMessages
{
    ClaimAvailableFunc = unlockable => new NotificationMessage
    {
        Title = "Unlockable reward available!",
        Body = $"The reward for the unlockable '{unlockable.Name}' is available to claim."
    }
};
unityMobileNotificationsSystem.ObserveSystem(unlockablesSystem, messages);
```

#### Energies System

```csharp
var energiesSystem = this.GetSystem<EnergiesSystem>();
var unityMobileNotificationsSystem = this.GetSystem<UnityMobileNotificationsSystem>();
var messages = new EnergiesNotificationMessages
{
    EnergyAccumulatedFunc = energy => new NotificationMessage
    {
        Title = "Energy available!",
        Body = $"You have new '{energy.Id}' available!"
    },
    EnergyMaxFunc = energy => new NotificationMessage
    {
        Title = "Energy is full!",
        Body = $"'{energy.Id}' is full, spend it now!"
    },
    EnergyRewardAccumulatedFunc = energy => new NotificationMessage
    {
        Title = "Reward Energy available!",
        Body = $"You have new '{energy.Id}' available!"
    },
    EnergyRewardMaxFunc = energy => new NotificationMessage
    {
        Title = "Reward Energy is full!",
        Body = $"'{energy.Id}' is full, claim your reward!"
    }
};
unityMobileNotificationsSystem.ObserveSystem(energiesSystem, messages);
```

### Manual scheduling

To manually schedule a notification with custom properties, you can use `ScheduleAdhocNotification`.

```csharp
var title = "Notification Title";
var body = "The description of the notification";
var scheduledDateTime = DateTime.Today.AddHours(1);

var identifier = unityMobileNotificationsSystem.ScheduleAdhocNotification(title, body, scheduledDateTime);
```

To cancel a scheduled notification you can use `CancelNotification`, passing in the notification's identifier.

```csharp
unityMobileNotificationsSystem.CancelAdhocNotification("<identifier>");
```
