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.

Feature Request Transactions with cost-per-unit and price breaks

Discussion in 'Game Foundation' started by jrmobley, Jul 29, 2020.

  1. jrmobley


    Feb 16, 2013
    Hey there Team Game Foundation,

    As I am continuing to develop my game and use Game Foundation, I have found that I would like to be able to use transactions to let the player purchase as much as they want when making virtual, non-IAP transactions.

    So for example, right now I have a transaction defined:
    costs: 100 coin
    rewards: 3 token
    (coin and token are both currencies)

    What I would like instead is something like:
    cost per token:
    30 coin each for 1 ~ 4 tokens
    25 coin each for 5 ~ 9 tokens
    20 coin each for 10 ~ 49 tokens
    15 coin each for 50+ tokens

    I could do this with some brute force with the current system by defining a transaction for each price point, adding some static properties that tell me where the price break points are, and executing a sequence of individual transactions. But it would be much better if I could execute a single transaction with a quantity parameter. It would be even better if the TransactionManager could identify the correct price point based on the requested quantity.

    Thanks for reading!
    erika_d likes this.
  2. mingz-unity


    Unity Technologies

    Oct 12, 2017
    Thanks for the question @jrmobley - to clarify my understanding, are you looking for a varying price point transaction system that can dynamically generate the pricing?

    For your described use case, Game Foundation provides transaction definitions for each 'bundle' of items, each can have its own cost-per-item, as the larger bundles are conventionally more heavily discounted in store.

    If you're looking for some sort of dynamic bundle with pricing generation based on some underlying per-unit cost rule, that would be a new requirement. We haven't seen too many examples on the market for this type of sales, or customer asks, but if you explain more of your rationale, or quote examples on how this can be a prevailing need, we can also prioritize that accordingly. As of now, given it's non-IAP, you may also try programmatically generating the transaction item as well as price point, to handle your custom need.

    Hope this helps.
    erika_d likes this.
  3. jrmobley


    Feb 16, 2013
    Yes, I think that is saying the same thing. ;)

    Indeed. I could offer the player a selection of bundles and have them choose to either buy 1, or buy 10, or buy or buy 50, with better value offered on larger bundles.

    Hmm... I suppose my rationale is to offer the player convenience and choice and a smooth purchasing flow.

    I did a quick survey of some of the games we play, and I certainly understand that the fixed bundles are common, but I have some screenshots from Love Nikki and Animal Crossing: Pocket Camp that show the per-unit style of transaction that I am thinking of.

    IMG_1673.PNG IMG_3144.PNG

    That is an interesting idea that I had not considered. If I understand correctly, I could get a transaction from the catalog that represents the appropriate per-unit cost, then use an API to create a modified copy where the costs and awards have been multiplied by the number of units the player has chosen, then execute my custom transaction. This way I can still take advantage of live-ops to maintain the catalog, but I can transact in arbitrary multiples in one go. Is that right? I will try that out.

    Thank you.
    erika_d likes this.
  4. mingz-unity


    Unity Technologies

    Oct 12, 2017
    Thanks for the additional details @jrmobley -

    For programmatically generating the transaction item, you'd still need to create the transaction definitions beforehand, so that the transaction system together with the data layer can all work correctly. So it's not a completely dynamic transaction / bundling system, as we don't support this scenario yet. But that hopefully can help with your use case if you want more variations on unit-per-item and the bundle types.

    Your examples are interesting - looks like these could be a dynamic transaction that vary by the quantity. For now, generating catalog item could be an option for you if the bundle types are still predictable, or you can execute multiple transactions to keep the purchase quantity flexible while working with a static catalog definition. i.e. you can apply a purchase X times if the quantity is given only at runtime. As for the varying costs, you can also set up a few 'presets' of bundles, so that with higher quantity, you can apply a different underlying transaction definition to repeat the purchase with, so that it can still create that varying unit-cost-per-item effect to some extent.

    Hope these help.
    erika_d likes this.
  5. jrmobley


    Feb 16, 2013
    Indeed, it does not seem to be possible to create a transaction at runtime.

    I have decided not to consider executing repeated transactions for two primary reasons:
    1. The overall transaction would no longer be atomic and could conceivably fail partway through.
    2. The analytics would be distorted and bloated.
    So for the time being, I will simply offer the user a small set of predefined bundle transactions.

    Just for reference, here are some details of my attempt to generate the desired transaction on demand at runtime:

    id: "buyTokens0", tags: "coins_per_token"
    costs: 10 coin, rewards: 1 token
    static properties:

    key: "minimum", value: 1
    id: "buyTokens1", tags: "coins_per_token"
    costs: 9 coin, rewards: 1 token
    static properties:

    key: "minimum", value: 5
    id: "buyTokens2", tags: "coins_per_token"
    costs: 8 coin, rewards: 1 token
    static properties:

    key: "minimum", value: 10

    Code (CSharp):
    2. public static class AllTheThings {
    4.     public static VirtualTransaction ChooseUnitTransaction(string tag, int multiple) {
    6.         var catalog = GameFoundation.catalogs.transactionCatalog;
    7.         var transactions = catalog.FindItemsByTag(tag);
    8.         VirtualTransaction unitTx = null;
    9.         int bestMinimumMultiple = 0;
    11.         foreach (var tx in transactions) {
    12.             var minProp = tx.GetStaticProperty("minimum");
    13.             var minMult = minProp.AsInt();
    14.             if (multiple >= minMult && minMult > bestMinimumMultiple) {
    15.                 unitTx = tx as VirtualTransaction;
    16.                 bestMinimumMultiple = minMult;
    17.             }
    18.         }
    20.         return unitTx;
    21.     }
    24.     public static VirtualTransaction MultiplyTransaction(VirtualTransaction unitTx, int multiple) {
    26.         var extendedTx = new VirtualTransactionConfig();
    28.         for (var k = 0; k < unitTx.costs.CurrencyExchangeCount; ++k) {
    29.             var unitCost = unitTx.costs.GetCurrencyExchange(k);
    30.             var extendedCost = new CurrencyExchangeDefinitionConfig {
    31.                 currency = unitCost.currency.key,
    32.                 amount = unitCost.amount * multiple
    33.             };
    34.             extendedTx.costs.currencies.Add(extendedCost);
    35.         }
    37.         for (var k = 0; k < unitTx.rewards.CurrencyExchangeCount; ++k) {
    38.             var unitReward = unitTx.rewards.GetCurrencyExchange(k);
    39.             var extendedReward = new CurrencyExchangeDefinitionConfig {
    40.                 currency = unitReward.currency.key,
    41.                 amount = unitReward.amount * multiple
    42.             };
    43.             extendedTx.rewards.currencies.Add(extendedReward);
    44.         }
    46.         /* At this point I would build a VirtualTransaction but I do not see any
    47.         way to do so with the Game Foundation API.  The methods are protected,
    48.         the catalogs are read-only... */
    50.         return null;
    51.     }
    52. }
    Thank you.
    erika_d and mingz-unity like this.
  6. jrmobley


    Feb 16, 2013
    While we are on the topic of fancy transactions, Love Nikki has another interesting feature that would require new features in Game Foundation: A VIP Loyalty program.

    Basically, you can earn VIP levels and those levels give you discounts on transactions. It would be impractical to pre-fill your catalog with every combination of transaction and discount. It is something you would have to do at runtime.

    Food for thought.

    IMG_1681.PNG IMG_1678.PNG
    Nefahl, erika_d and mingz-unity like this.