Skip to content

Content Management System

CMS (Content Management System) is an essential part of Balancy. It is used for creating data structure and editing the data. Balancy automatically delivers the newest data to the app and parses it to the convenient auto-generated code, so you can easily access it.

How Does it Work?

  1. You can add all types of objects your game has: weapon, item, construction, monster, hero, location, etc...
  2. You can add as many documents as possible for each type of object. Each document represents a unique weapon, item, construction, etc...
  3. Open your project in Unity and start code generation requests. Balancy will automatically generate the code based on the data you provided.
  4. Once the game is launched, all the game data is delivered to the game and already mapped to the generated code.
  5. Your programmer has direct access to your game's items, weapons, and other objects. He doesn't have to write any code for downloading or parsing.
  6. All changes in Balancy will be automatically synchronized with the game on launch. You must deploy changes.

Templates

Template describes the structure and behavior of your game object (item, monster, construction,...). As a programmer, you can think of it as a class. The template has to have a unique name and may contain a set of parameters.

  1. Open the Data Structure section, you'll land on the Templates subsection by default. Click on the Create Template button.

    Screenshot

  2. Each Template has several parameters.

    Name Description
    Name This very name is used for class generation. To keep everything in style, we advise using CamelCase naming.

    For example: ItemModel, GameConstruction, MonsterData,...
    Display Name The name will be displayed in Balancy. Usually, it's the same as the name, but the words are separated.

    For example, Item Model, Game Construction, Monster Data,...
    Description Helps other team members to understand what this Template is used for easily.
    Base Template It's used if your Template inherits from another one.
    Type Can be Document, Component, or Singleton:

    * Component Documents of this Template are always embedded into other Documents. For example, the Vector3 component template has parameters: x, y, and z. Suppose a Document "Hero" has a Parameter "position" of type Vector3. In that case, you'll be able to edit the x, y, and z values of "position" right inside of the "Hero" Document.

    * Singleton Only one of such Documents will be available from the code. It's usually used for settings and configs.
    Flags Optional settings for the Template
    Custom Display format Defines the display rules for Documents of the Template. It's handy for complex Templates. You can read more here)

Flags

You can set optional flags for the template.

Flag name Description
Abstract Generated class for this template will be abstract.
Partial Generated class for this template will be partial. Helpful when you want to extend functionality of the class.
Don't generate any code Class will not be generated and the code in Editor class will not be generated.
Don't generate class file Class for this template will not be generated.
Can't inherit Prevents inheritance from this template.
Hide from navigation Hides documents section from the left navigation menu.
Internal Makes template visible only inside the namespace, if it is used in template name.
Hide id Hides id from the document display name.
Static in clones If set, template will replace existing template on the package import.
Generate as enum Will generate additional enum to list all the documents of that template for easy referencing in client code.
Don't generate JSONs Allows to save memory, if JSON format will never be used for these documents.
Prevent access outside package Similar to Internal, but on package level.
Don't generate on Deploy Useful for parameters which are just personal helpers for Balancy users, such as Comment or Description.

Documents

The document is a unique instance of a Template (Specific Item: Hunter's Bow, Gold Bar,...) with its parameter values. Think of it as an instance of a Class as a programmer.

A new section in the left navigation appears when you add a new Template (Not a Component). If you select any of the Document sections, you can add new Documents there. Each document can have a unique value for all its Template parameters.

Components

The component is a simple Template, which doesn't have its Documents and can exist only inside another Document.

For example, the ItemActionWeapon (inherited from ItemAction) component template has parameters: damage and reload. If a Document "Item" has a Parameter "action" of type ItemAction, you'll be able to edit the damage and reload values of "action" right inside of the "Item" Document.

Injected Components

Injected components are similar to Components, except the following:

  1. You can Override or A/B Test only internal parameters of Injected Components, not a component as a whole.
  2. You cannot override parameters that are lists of Injected Components.
  3. Inheritance doesn't work for Injected Components
  4. Injected Components don't create an independent JSON file when the data is Deployed. Instead, they inject the parameter right where they are used.
  5. Injected Components work slightly faster.

For example, the Vector3 component template has parameters: x, y, and z. If a Document "Hero" has a Parameter "position" of type Vector3, you'll be able to edit the x, y, and z values of "position" right inside of the "Hero" Document.

Parameters

Parameter describes a part of a Document, storing some value. Each parameter has a name and a type. Type can be simple, like string, int, float, bool, or a reference to any other Template. As a programmer, you can think of a parameter as a field or property of the class.

  1. After creating a template, you can add parameters to it. Screenshot

  2. On the parameters page, you can view/edit all existing parameters and add a new one.

  3. Each Parameter has several fields:

    Name Description
    Name This very name is used during Class generation. To keep everything in style, we advise you to use CamelCase naming.

    For example: MainTag, ConstructionId, HeroType,...
    Display Name This name will be displayed in Balancy for your convenience.

    For example, Main Tag, Construction Id, Hero Type,...
    Description Helps other team members to understand what this Parameter is used for easily.
    Default Value The value assigned by default upon creating a new document.
    Type A Data type of the parameter. All types are below.
    Type Description
    Integer A Number that can be written without a fractional component. For example, 1, 2, 999, -200
    Float A Number with a fractional component. For example, 1.32, -0.7432
    Boolean Logical value: true or false
    String Any Text. For ex: "Hello World", "-+ ta-ta_!! 55"
    Enum Provides a selection from predefined possible values.
    Document A reference to an existing document
    List An Array(list) of other type values
    Asset A reference to an existing Asset. It's usually a prefab, sprite, or other Object stored in a Unity game as an Addressable.
    Sprite A reference to an existing Sprite, that you can upload to the CDN using Balancy.
    Date Time A date with time. E. g. 1970-01-01T00:00. Have a nice picker inside the table.
    Duration Similar to integer, but have a nice UI to separate days, hours, minutes, and seconds.
    Product Reference to in-game purchase item.

Enumerated Types

Enumerated types are widely used in programming. When you have a limited list of possible values, using enum instead of int or string is often convenient.

Example

If you have a limited set of Colors to choose from in your game, you should store the value as an integer (1,2,3,4,...) to save memory. However, you can define a new enum, making your values more readable and convenient.

public enum Color
{
    Red = 0,
    Green = 1,
    Blue = 2,
    White = 3,
    Black = 4,
}

Now you can use values like Color.Blue in your code instead of 2.

How to create an enum

  1. Select the Data Structure section.
  2. Switch to the Enums subsection.
  3. Click on the Create Enum button.

    Screenshot

  4. Each Enum has several parameters.

    Name Description
    Name This name is used when you work with your enum from code.
    Display Name The name displayed in Balancy.
    Description Helps other team members to understand what this Enum is used for easily.
    Multi-selection Defines if a parameter can contain multiple enum values.
  5. Each enum value must have a unique name and a unique value associated with the name. If you use Multi-selection, all the values must be a power of 2 or equal to zero.

  6. When you create and save your enum, you can choose the type Enum for a parameter.

    Screenshot

Assets

Assets are all objects which you store in Addressables. If you are not using Addressables in your game, you should ignore this page or better start using them.

  1. In Unity Open Tools ► Balancy ► Config and click on Synch Addressables.
  2. The synchronization process starts.
  3. Balancy detects which Addressables were changed after the last synchronization and only uploads images for the new/updated files. The first synchronization might take some time, while all subsequent will be faster.
  4. After the process, open the Data Structure ► Assets section in Balancy, and you should see the list of all your Assets. Screenshot

  5. If you have any parameter of type Asset, you'll be able to pick it from the dropdown menu: Screenshot

  6. In the generated code, your parameter will have the type UnnyAsset. It has only one field Name, enough for a developer to load the addressable.

Sprites

Sprites are digital assets that can be uploaded to the Content Delivery Network (CDN) via Balancy. These assets are dynamically delivered at runtime, enabling the game to use updated visual content without the need for patching or direct updates. Currently, Balancy supports the uploading of images in PNG and JPEG formats.

Sprites in Balancy

Adding Sprites

To use sprites in your game:

  1. When defining a new parameter, select the type Sprite.
  2. You can then insert links to your uploaded images in your documentation.

For Developers

The code generator automatically sets the type for Sprite parameters as UnnyObject, which includes a method LoadSprite for asynchronous loading. All images are cached locally at PersistanceDataPath to minimize download times and bandwidth usage.

Best Practices

Sprites are invaluable for adding dynamic content to game offers and the shop interface. They can significantly enhance the game's visual appeal by allowing for the customization of backgrounds, buttons, and other game art remotely. However, managing these assets efficiently is crucial to avoid duplication and bloat:

  1. Avoid Manual Sprite Addition: Instead of adding sprites directly to the game, upload them to Balancy.
  2. Use Balancy for All Sprites: Upload necessary sprites to Balancy for use in your game.
  3. Flag Important Sprites: For sprites that need to be included in the initial game build, such as default buttons and background images, mark them with the Save in Resources flag. This is typically unnecessary for dynamic offer sprites.
  4. Sync with Unity: In Unity, navigate to Tools ► Balancy ► Config and select Download Data to synchronize.
  5. Access Sprites from Resources: Sprites marked with the Save in Resources flag can be found under Assets/Balancy/Resources.

Tip: Although sprites are identified by unique IDs, making direct references less convenient, future updates may introduce name-based referencing for improved ease of use.

  1. Build Prefabs Using Resources: Construct default prefabs for shops and offers using sprites from the Resources directory.
  2. Avoid Duplicate Sprites: This method ensures no sprite duplication within your build while maintaining flexibility for remote updates.
  3. Null Check in Code: When replacing a default sprite, ensure the new sprite is not null before assignment to avoid removing default imagery.
myItem.Icon.LoadSprite(sprite =>
{
    if (sprite != null)
        icon.sprite = sprite;
});