Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Creating GameFoundation Database from code

Discussion in 'Game Foundation' started by VektaCo, Jun 16, 2020.

  1. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    Is there a way I can create the GameFoundationDatabase from code, rather than having to manually enter everything.

    I import and parse all my data from a Spreadsheet (during Editor time) and I wanted to try switch over to GameFoundation, but this is stopping me.

    something like GameFoundationEditor.AddInventoryItem(Args)
     
    erika_d likes this.
  2. mingz-unity

    mingz-unity

    Unity Technologies

    Joined:
    Oct 12, 2017
    Posts:
    62
    Hi @VektaCo - yes the team has recently implemented public API that allows programmatic control of Game Foundation catalog data, mainly to support data import use cases like yours. The feature isn't released yet, but we plan to include that in the next release.

    If this is currently blocking your project, please DM me with your email contact information. I can provide you with a preview build right now.
     
    Last edited: Jun 16, 2020
    VektaCo, erika_d and saskenergy like this.
  3. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    mingz-unity likes this.
  4. mingz-unity

    mingz-unity

    Unity Technologies

    Joined:
    Oct 12, 2017
    Posts:
    62
    Hi @VektaCo - we just released 0.6.0 package, and in this newest version you ca use the public API to create and update game foundation database.

    The API is not fully documented with tutorials yet (as it's for more advanced users), but here's an example that can help you to get started:

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using MiniJSON;
    4. using UnityEditor;
    5. using UnityEditor.GameFoundation.DefaultCatalog.Details;
    6. using UnityEngine;
    7. using UnityEngine.GameFoundation;
    8. using UnityEngine.GameFoundation.DefaultCatalog;
    9. using UnityEngine.GameFoundation.DefaultCatalog.Details;
    10. using static TestDatabaseConstants;
    11. using static TestDatabaseConstants.InventoryItems;
    12. using static TestDatabaseConstants.JsonDetailConstants;
    13.  
    14. public static class TestDatabaseConstants
    15. {
    16.     public const string kDatabaseName = "TestDatabase2";
    17.     public const string kDatabasePath = "Assets/TestDatabase2.asset";
    18.  
    19.     public static class Tags
    20.     {
    21.         public const string kMoney_Key = "MONEY";
    22.         public const string kResource_Key = "RESOURCE";
    23.         public const string kEquipment_Key = "EQUIPMENT";
    24.         public const string kConsumable_Key = "CONSUMABLE";
    25.         public const string kConsumablePacks_Key = "CONSUMABLE_PACKS";
    26.         public const string kXmas20_Key = "XMAS_20_PACKS";
    27.         public const string kSpecialEvent_Key = "SPECIAL_EVENT";
    28.     }
    29.  
    30.     public static class Currencies
    31.     {
    32.         public const string kCoin_Key = "COIN";
    33.         public const string kCoin_DisplayName = "Coin";
    34.         public const long kCoin_InitialBalance = 0;
    35.         public const long kCoin_MaximumBalance = 0;
    36.  
    37.         public const string kStone_Key = "STONE";
    38.         public const string kStone_DisplayName = "Stone";
    39.         public const long kStone_InitialBalance = 100;
    40.         public const long kStone_MaximumBalance = 0;
    41.  
    42.         public const string kWood_Key = "WOOD";
    43.         public const string kWood_DisplayName = "Wood";
    44.         public const long kWood_InitialBalance = 0;
    45.         public const long kWood_MaximumBalance = 10000;
    46.     }
    47.  
    48.     public static class InventoryItems
    49.     {
    50.         public static class MagicalSword
    51.         {
    52.             public const string key = "MAGICAL_SWORD";
    53.             public const string displayName = "Magical Sword";
    54.  
    55.             public const string wearPropertyKey = "WEAR";
    56.             public const int wearPropertyDefaultValue = 10;
    57.         }
    58.  
    59.         public static class EtherealShield
    60.         {
    61.             public const string key = "ETHEREAL_SHIELD";
    62.             public const string displayName = "Ethereal Shield";
    63.  
    64.             public const string wearPropertyKey = "WEAR";
    65.             public const int wearPropertyDefaultValue = 99;
    66.         }
    67.  
    68.         public static class FabulousDragon
    69.         {
    70.             public const string key = "FABULOUS_DRAGON";
    71.             public const string displayName = "Fabulous dragon";
    72.  
    73.             public const string isTamedPropertyKey = "IS_TAMED";
    74.             public const bool isTamedPropertyDefaultValue = true;
    75.  
    76.             public const string nicknamePropertyKey = "NICKNAME";
    77.             public const string nicknamePropertyDefaultValue = "Rex";
    78.         }
    79.  
    80.         public static class HealthPotion
    81.         {
    82.             public const string key = "HEALTH_POTION";
    83.             public const string displayName = "Health Potion";
    84.  
    85.             public const string fillRatePropertyKey = "FILL_RATE";
    86.             public const float fillRatePropertyDefaultValue = 100f;
    87.         }
    88.  
    89.         public static class EmptyItem
    90.         {
    91.             public const string key = "EMPTY";
    92.             public const string displayName = "Empty";
    93.         }
    94.     }
    95.  
    96.     public static class Transactions
    97.     {
    98.         public const string kStarterPack_Key = "STARTER_PACK";
    99.         public const string kStarterPack_DisplayName = "Starter Pack";
    100.         public const long kStarterPack_Cost_Coin = 100;
    101.         public const long kStarterPack_Reward_Stone = 5000;
    102.         public const long kStarterPack_Reward_Wood = 10000;
    103.         public const long kStarterPack_Reward_HealthPotion = 10;
    104.  
    105.         public const string kJingleBell_Key = "JINGLE_BELL";
    106.         public const string kJingleBell_DisplayName = "Jingle Bell";
    107.         public const string kJingleBell_AppleId = "com.test.apple.id";
    108.         public const string kJingleBell_GoogleId = "com.test.google.id";
    109.         public const long kJingleBell_Reward_Coin = 1000;
    110.         public const long kJingleBell_Reward_Stone = 50000;
    111.         public const long kJingleBell_Reward_Wood = 100000;
    112.         public const long kJingleBell_Reward_MagicalSword = 1;
    113.         public const long kJingleBell_Reward_EtherealShield = 1;
    114.         public const long kJingleBell_Reward_HealthPotion = 50;
    115.     }
    116.  
    117.     public static class Stores
    118.     {
    119.         public const string kMain_Key = "main";
    120.         public const string kMain_DisplayName = "Main";
    121.  
    122.         public const string kXmas20_Key = "XMAS20_STORE";
    123.         public const string kXmas20_DisplayName = "Christmas 2020 Store";
    124.     }
    125.  
    126.     public static class AssetDetailConstants
    127.     {
    128.         public const string kIcon_Name = "Icon";
    129.         public const string kIcon_ResourcesPath = "Test_Sprites/Square";
    130.  
    131.         public const string kSmallIcon_Name = "Small_Icon";
    132.         public const string kSmallIcon_ResourcesPath = "Test_Sprites/Triangle";
    133.  
    134.         public const string kButtonIcon_Name = "Button_Icon";
    135.         public const string kButtonIcon_ResourcesPath = "Test_Sprites/Circle";
    136.     }
    137.  
    138.     public static class JsonDetailConstants
    139.     {
    140.         public const string bool_Key = "testBool";
    141.         public const bool bool_Value = true;
    142.  
    143.         public const string int_Key = "testInt";
    144.         public const int int_Value = 42;
    145.  
    146.         public const string long_Key = "testLong";
    147.         public const long long_Value = 1337;
    148.  
    149.         public const string float_Key = "testFloat";
    150.         public const float float_Value = 13.37f;
    151.  
    152.         public const string double_Key = "testDouble";
    153.         public const double double_Value = 13.37;
    154.  
    155.         public const string date_Key = "testDate";
    156.         public static readonly DateTime date_Value = DateTime.Parse("2020-04-08T13:37:42");
    157.  
    158.         public const string string_Key = "testString";
    159.         public static readonly string string_Value = "Lorem ipsum";
    160.  
    161.         public const string boolArray_Key = "testBoolArray";
    162.         public static readonly bool[] boolArray_Value = { true, false };
    163.  
    164.         public const string intArray_Key = "testIntArray";
    165.         public static readonly int[] intArray_Value = { 3, 1415927 };
    166.  
    167.         public const string longArray_Key = "testLongArray";
    168.         public static readonly long[] longArray_Value = { 3L, 1415927L };
    169.  
    170.         public const string floatArray_Key = "testFloatArray";
    171.         public static readonly float[] floatArray_Value = { 3f, 1415927f };
    172.  
    173.         public const string doubleArray_Key = "testDoubleArray";
    174.         public static readonly double[] doubleArray_Value = { 3.0, 1415927.0 };
    175.  
    176.         public const string dateArray_Key = "testDateArray";
    177.         public static readonly DateTime[] dateArray_Value = { DateTime.Parse("2020-04-08T13:37:42"), DateTime.Parse("2020-04-08T00:00:00") };
    178.  
    179.         public const string stringArray_Key = "testStringArray";
    180.         public static readonly string[] stringArray_Value = { "Lorem", "Ipsum" };
    181.  
    182.         public const string dictionary_Key = "testDictionary";
    183.         public static readonly Dictionary<string, object> dictionary_Value = new Dictionary<string, object>
    184.         {
    185.             ["intKey"] = 4016534536,
    186.             ["boolKey"] = false,
    187.             ["nullKey"] = null,
    188.         };
    189.     }
    190. }
    191.  
    192. public static class TestDatabaseCreator2
    193. {
    194.     [MenuItem("Window/Game Foundation/Tests/Initialize Database 2", priority = 2200)]
    195.     static void InitializeDatabaseMenuItem()
    196.     {
    197.         s_Database = ScriptableObject.CreateInstance<GameFoundationDatabase>();
    198.         s_Database.name = kDatabaseName;
    199.  
    200.         InitializeTagCatalog(s_Database);
    201.         InitializeCurrencyCatalog(s_Database);
    202.         InitializeInventoryCatalog(s_Database);
    203.         InitializeTransactionCatalog(s_Database);
    204.         InitializeStoreCatalog(s_Database);
    205.  
    206.         s_Database.Save(kDatabasePath);
    207.     }
    208.  
    209.     static string CreateJsonData()
    210.     {
    211.         var testData = new JsonData();
    212.         testData.TryAddData(int_Key, int_Value);
    213.         testData.TryAddData(long_Key, long_Value);
    214.         testData.TryAddData(bool_Key, bool_Value);
    215.         testData.TryAddData(date_Key, date_Value);
    216.         testData.TryAddData(float_Key, float_Value);
    217.         testData.TryAddData(double_Key, double_Value);
    218.         testData.TryAddData(string_Key, string_Value);
    219.         testData.TryAddData(intArray_Key, intArray_Value);
    220.         testData.TryAddData(longArray_Key, longArray_Value);
    221.         testData.TryAddData(boolArray_Key, boolArray_Value);
    222.         testData.TryAddData(dateArray_Key, dateArray_Value);
    223.         testData.TryAddData(floatArray_Key, floatArray_Value);
    224.         testData.TryAddData(doubleArray_Key, doubleArray_Value);
    225.         testData.TryAddData(stringArray_Key, stringArray_Value);
    226.         testData.TryAddData(dictionary_Key, dictionary_Value);
    227.  
    228.         return Json.Serialize(testData.ToDictionary());
    229.     }
    230.  
    231.     public static void AddRange<T>(this ICollection<T> @this, params T[] elements)
    232.     {
    233.         foreach (var element in elements)
    234.         {
    235.             @this.Add(element);
    236.         }
    237.     }
    238.  
    239.     static GameFoundationDatabase s_Database;
    240.  
    241.     static void AddAnalyticsDetail(CatalogItemAsset asset)
    242.     {
    243.         asset.AddDetail<AnalyticsDetailAsset>();
    244.     }
    245.  
    246.     static void InitializeTagCatalog(GameFoundationDatabase database)
    247.     {
    248.         database.CreateTag(Tags.kMoney_Key);
    249.         database.CreateTag(Tags.kResource_Key);
    250.         database.CreateTag(Tags.kEquipment_Key);
    251.         database.CreateTag(Tags.kConsumable_Key);
    252.         database.CreateTag(Tags.kConsumablePacks_Key);
    253.         database.CreateTag(Tags.kXmas20_Key);
    254.         database.CreateTag(Tags.kSpecialEvent_Key);
    255.     }
    256.  
    257.     static void InitializeCurrencyCatalog(GameFoundationDatabase database)
    258.     {
    259.         CurrencyAsset Currency(
    260.             string key, string displayName,
    261.             long initialBalance, long maximumBalance,
    262.             CurrencyType type, string tagKey)
    263.         {
    264.  
    265.             var currency = database.CreateCurrency(key);
    266.             currency.SetDisplayName(displayName);
    267.             currency.SetInitialBalance(initialBalance);
    268.             currency.SetMaximumBalance(maximumBalance);
    269.             currency.SetType(type);
    270.             var tag = database.tagCatalog.FindTag(tagKey);
    271.             currency.AddTag(tag);
    272.             currency.AddDetail<AnalyticsDetailAsset>();
    273.  
    274.             return currency;
    275.         }
    276.  
    277.         // Currencies
    278.  
    279.         Currency(
    280.             Currencies.kCoin_Key, Currencies.kCoin_DisplayName,
    281.             Currencies.kCoin_InitialBalance, Currencies.kCoin_MaximumBalance,
    282.             CurrencyType.Hard, Tags.kMoney_Key);
    283.  
    284.         Currency(
    285.             Currencies.kStone_Key, Currencies.kStone_DisplayName,
    286.             Currencies.kStone_InitialBalance, Currencies.kStone_MaximumBalance,
    287.             CurrencyType.Soft, Tags.kResource_Key);
    288.  
    289.         Currency(
    290.             Currencies.kWood_Key, Currencies.kWood_DisplayName,
    291.             Currencies.kWood_InitialBalance, Currencies.kWood_MaximumBalance,
    292.             CurrencyType.Soft, Tags.kResource_Key);
    293.     }
    294.  
    295.     static void InitializeInventoryCatalog(GameFoundationDatabase database)
    296.     {
    297.         var catalog = database.inventoryCatalog;
    298.  
    299.         InventoryItemDefinitionAsset CreateItem(string key, string displayName)
    300.         {
    301.             var item = database.CreateInventoryItem(key);
    302.             item.SetDisplayName(displayName);
    303.             item.AddDetail<AnalyticsDetailAsset>();
    304.             return item;
    305.         }
    306.  
    307.         InventoryItemDefinitionAsset Item<TProperty>(
    308.             string key, string displayName,
    309.             string propertyKey, TProperty value,
    310.             string tagKey)
    311.         {
    312.             var item = CreateItem(key, displayName);
    313.             item.AddTag(database.tagCatalog.FindTag(tagKey));
    314.  
    315.             var propertyType = typeof(TProperty);
    316.             Property propertyValue;
    317.             if (propertyType == typeof(int)
    318.                 || propertyType == typeof(long))
    319.             {
    320.                 propertyValue = Convert.ToInt64(value);
    321.             }
    322.             else if (propertyType == typeof(float)
    323.                 || propertyType == typeof(double))
    324.             {
    325.                 propertyValue = Convert.ToDouble(value);
    326.             }
    327.             else if (propertyType == typeof(bool))
    328.                 propertyValue = Convert.ToBoolean(value);
    329.             else if (propertyType == typeof(string))
    330.                 throw new NotImplementedException();
    331.             else
    332.                 throw new ArgumentException($"{propertyType.Name} isn't a valid type for properties.");
    333.  
    334.             item.AddProperty(propertyKey, propertyValue);
    335.  
    336.             return item;
    337.         }
    338.  
    339.         // Items
    340.  
    341.         var magicalSword = Item(
    342.             MagicalSword.key, MagicalSword.displayName,
    343.             MagicalSword.wearPropertyKey, MagicalSword.wearPropertyDefaultValue,
    344.             Tags.kEquipment_Key);
    345.  
    346.         var jsonDetail = magicalSword.AddDetail<JsonDetailAsset>();
    347.  
    348.         jsonDetail.SetJsonData(CreateJsonData());
    349.  
    350.         var assetDetail = magicalSword.AddDetail<AssetsDetailAsset>();
    351.         assetDetail.AddAsset(AssetDetailConstants.kIcon_Name, AssetDetailConstants.kIcon_ResourcesPath);
    352.         assetDetail.AddAsset(AssetDetailConstants.kSmallIcon_Name, AssetDetailConstants.kSmallIcon_ResourcesPath);
    353.         assetDetail.AddAsset(AssetDetailConstants.kButtonIcon_Name, AssetDetailConstants.kButtonIcon_ResourcesPath);
    354.  
    355.         var fabulousDragon = Item(
    356.             FabulousDragon.key, FabulousDragon.displayName,
    357.             FabulousDragon.isTamedPropertyKey, FabulousDragon.isTamedPropertyDefaultValue,
    358.             Tags.kEquipment_Key);
    359.         fabulousDragon.AddProperty(FabulousDragon.nicknamePropertyKey, FabulousDragon.nicknamePropertyDefaultValue);
    360.  
    361.         Item(
    362.             EtherealShield.key, EtherealShield.displayName,
    363.             EtherealShield.wearPropertyKey, EtherealShield.wearPropertyDefaultValue,
    364.             Tags.kEquipment_Key);
    365.         Item(
    366.             HealthPotion.key, HealthPotion.displayName,
    367.             HealthPotion.fillRatePropertyKey, HealthPotion.fillRatePropertyDefaultValue,
    368.             Tags.kConsumable_Key);
    369.  
    370.         CreateItem(EmptyItem.key, EmptyItem.displayName);
    371.     }
    372.  
    373.     static void InitializeStoreCatalog(GameFoundationDatabase database)
    374.     {
    375.         var catalog = database.storeCatalog;
    376.  
    377.         var transactions = database.transactionCatalog;
    378.  
    379.         // Stores
    380.  
    381.         {
    382.             var mainStore = catalog.FindItem(Stores.kMain_Key);
    383.             Debug.Assert(mainStore != null, $"Store {Stores.kMain_Key} not found");
    384.             mainStore.AddDetail<AnalyticsDetailAsset>();
    385.  
    386.             {
    387.                 var transaction = transactions.FindItem(Transactions.kJingleBell_Key);
    388.                 mainStore.AddTransaction(transaction, false);
    389.             }
    390.  
    391.             {
    392.                 var transaction = transactions.FindItem(Transactions.kStarterPack_Key);
    393.                 mainStore.AddTransaction(transaction);
    394.             }
    395.         }
    396.  
    397.         {
    398.             var xMasStore = database.CreateStore(Stores.kXmas20_Key);
    399.             xMasStore.SetDisplayName(Stores.kXmas20_DisplayName);
    400.  
    401.  
    402.             var tag = database.tagCatalog.FindTag(Tags.kSpecialEvent_Key);
    403.             xMasStore.AddTag(tag);
    404.             xMasStore.AddDetail<AnalyticsDetailAsset>();
    405.  
    406.             {
    407.                 var transaction = transactions.FindItem(Transactions.kJingleBell_Key);
    408.                 xMasStore.AddTransaction(transaction);
    409.             }
    410.         }
    411.     }
    412.  
    413.     static void InitializeTransactionCatalog(GameFoundationDatabase database)
    414.     {
    415.         var catalog = database.transactionCatalog;
    416.  
    417.         var currencyCatalog = database.currencyCatalog;
    418.         var itemCatalog = database.inventoryCatalog;
    419.  
    420.         // Virtual transactions
    421.  
    422.         var starterPack = database.CreateVirtualTransaction(Transactions.kStarterPack_Key);
    423.         starterPack.SetDisplayName(Transactions.kStarterPack_DisplayName);
    424.         var tag = database.tagCatalog.FindTag(Tags.kConsumablePacks_Key);
    425.         starterPack.AddTag(tag);
    426.  
    427.         starterPack.AddDetail<AnalyticsDetailAsset>();
    428.  
    429.         starterPack.AddCost(currencyCatalog.FindItem(Currencies.kCoin_Key), Transactions.kStarterPack_Cost_Coin);
    430.  
    431.         starterPack.AddReward(currencyCatalog.FindItem(Currencies.kStone_Key), Transactions.kStarterPack_Reward_Stone);
    432.         starterPack.AddReward(currencyCatalog.FindItem(Currencies.kWood_Key), Transactions.kStarterPack_Reward_Wood);
    433.         starterPack.AddReward(itemCatalog.FindItem(HealthPotion.key), Transactions.kStarterPack_Reward_HealthPotion);
    434.  
    435.         // IAP transactions
    436.  
    437.         var jingleBell = database.CreateIapTransaction(Transactions.kJingleBell_Key);
    438.         jingleBell.SetDisplayName(Transactions.kJingleBell_DisplayName);
    439.         tag = database.tagCatalog.FindTag(Tags.kXmas20_Key);
    440.         jingleBell.AddTag(tag);
    441.  
    442.         jingleBell.SetAppleId(Transactions.kJingleBell_AppleId);
    443.         jingleBell.SetGoogleId(Transactions.kJingleBell_GoogleId);
    444.         jingleBell.AddDetail<AnalyticsDetailAsset>();
    445.  
    446.         jingleBell.AddReward(currencyCatalog.FindItem(Currencies.kCoin_Key), Transactions.kJingleBell_Reward_Coin);
    447.         jingleBell.AddReward(currencyCatalog.FindItem(Currencies.kStone_Key), Transactions.kJingleBell_Reward_Stone);
    448.         jingleBell.AddReward(currencyCatalog.FindItem(Currencies.kWood_Key), Transactions.kJingleBell_Reward_Wood);
    449.         jingleBell.AddReward(itemCatalog.FindItem(HealthPotion.key), Transactions.kJingleBell_Reward_HealthPotion);
    450.         jingleBell.AddReward(itemCatalog.FindItem(MagicalSword.key), Transactions.kJingleBell_Reward_MagicalSword);
    451.         jingleBell.AddReward(itemCatalog.FindItem(EtherealShield.key), Transactions.kJingleBell_Reward_EtherealShield);
    452.     }
    453. }
    454.  
     
    GilbertoBitt and VektaCo like this.
  5. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    Thank you @mingz-unity!
    I'll give it a try this week

    *Update, works great. Thanks!
     
    Last edited: Jul 12, 2020
    mingz-unity and GilbertoBitt like this.
  6. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    @mingz-unity issues I'm having when auto-importing

    Major
    AddStaticProperty is not filling the key value field
    upload_2020-7-12_14-4-45.png

    Minor
    I have to delete the the old Database before I call save, and then manually update the GameFoundationDatabaseSettings. Is there a way to overwrite the database, or auto update the settings file.
     
  7. mingz-unity

    mingz-unity

    Unity Technologies

    Joined:
    Oct 12, 2017
    Posts:
    62
    @VektaCo I'll forward this to the team and get back to you on our findings. Thanks for the details.
     
    VektaCo likes this.
  8. erika_d

    erika_d

    Unity Technologies

    Joined:
    Jan 20, 2016
    Posts:
    413
    VektaCo likes this.
  9. itsarjunsinh

    itsarjunsinh

    Joined:
    Nov 9, 2019
    Posts:
    16
    This would work at runtime, right? I'm planning to first fetch data from Firebase/Local Cache on end user devices and then pass it into gamefoundation framework.
     
  10. richj_unity

    richj_unity

    Unity Technologies

    Joined:
    Sep 23, 2019
    Posts:
    40
    Unfortunately not currently. There is an IExternalValueProvider interface for overriding individual parts of a definition, but the means of creating new definition assets is limited to edit mode (it would break when you go to do a build). The concept also exists of using a different data layer to load a remote catalog (for example some kind of FirebaseAdapter), but we don't support that yet.
     
    itsarjunsinh and erika_d like this.
  11. Raghavendra

    Raghavendra

    Joined:
    Mar 14, 2014
    Posts:
    52
    You can try fetching the values from remote config and then assign them to GameFoundation. I am doing the same for Cloud save values.
     
    erika_d likes this.
  12. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    @erika_d Will setting Initial Allocation and Mutable Properties be available in the next release?
     
  13. erika_d

    erika_d

    Unity Technologies

    Joined:
    Jan 20, 2016
    Posts:
    413
    Hi @VektaCo,

    Just to confirm, do you mean Setting the Initial Allocation and adding Mutable Properties in the editor API? If so, I believe these methods from our 0.8 release will do what you're looking for? If not can you give me more info about what you're looking for?
     
    VektaCo likes this.
  14. VektaCo

    VektaCo

    Joined:
    Sep 30, 2019
    Posts:
    31
    @erika_d Perfect!
    I was using the base CatalogItemAsset instead of InventoryItemDefinitionAsset by mistake.
     
    erika_d likes this.