Skip to content

Template: Merge Game

Screenshot

Merge games - a captivating sub-genre of puzzle games where players combine identical items to create new, more advanced ones. These games have grown exponentially, captivating audiences with their intuitive mechanics and rewarding progression systems.

At the core of merge games are intricate items with unique attributes and functionalities. Some items can boost your progress, while others might be split, downgraded, or transformed in diverse ways. Given this complexity, developers often need help storing and managing these myriad items with varying settings.

To assist with this, we've crafted a comprehensive template to address many common questions and challenges you might face.

For more insights, don't hesitate to explore an article on our blog. While it discusses a solution tailored for survival games, the underlying principles are versatile and can be adapted for merge games.

Dive in, and equip yourself with the knowledge to take your merge game development to the next level!

Items

Items are the core of any merge game. Each item has a lot of parameters, but the most important one is Item Effects, here you define all unique features of each item.

Screenshot

If you need to add a new Effect, just create a new Template, inherited from Item Effect Base. You can create any required parameters for that Template.

Screenshot

Once the Template is created, you'll be able to use it in the Item's table:

Screenshot

Spawners

Spawners are Items, which can generate other Items. You can define drop in the Drop parameter. Other parameters are example how you can work with Energy usage and restoration for Spawners.

Screenshot

Section for programmers

Extension for GameItem

using UnityEngine;

namespace Balancy.Models.MergeGame
{
    public static class GameItemExtension
    {
        public static GameItem GetNextLevelItem(this GameItem item)
        {
            return item.MergeItem as GameItem;
        }

        public static bool CanCut(this GameItem item)
        {
            return item.HasEffect<ItemEffectCut>();
        }

        public static bool CanAutoDrop(this GameItem item)
        {
            return item.HasEffect<ItemEffectAutoDrop>();
        }

        public static bool CanDowngrade(this GameItem item)
        {
            return item.HasEffect<ItemEffectDowngradable>();
        }

        public static ItemEffectBubble GetBubbleEffect(this GameItem item)
        {
            return item.GetEffect<ItemEffectBubble>();
        }

        public static bool HasEffect<T>(this GameItem item) where T : ItemEffectBase
        {
            return item.GetEffect<T>() != null;
        }

        public static T GetEffect<T>(this GameItem item) where T : ItemEffectBase
        {
            foreach (var effect in item.ItemEffects)
            {
                if (effect is T t)
                    return t;
            }

            return null;
        }

        public static void PrintAllItems()
        {
            foreach (var item in DataEditor.MergeGame.GameItems)
                item.PrintInfo();
        }

        public static void PrintInfo(this GameItem item)
        {
            Debug.LogWarning($"Item {item.Name} level {item.Level}");
            Debug.Log($"CanCut {item.CanCut()}");
            Debug.Log($"CanAutoDrop {item.CanAutoDrop()}");
            Debug.Log($"CanDowngrade {item.CanDowngrade()}");
            Debug.Log($"GetBubbleEffect {item.GetBubbleEffect()}");
        }
    }
}

Extension for Spawners

using UnityEngine;

namespace Balancy.Models.MergeGame
{
    public static class SpawnerExtension
    {
        public static GameItem DropRandomItem(this Spawner spawner)
        {
            var allWeight = spawner.CalculateTotalDropWeight();

            var random = Balancy.Random.Range(0, allWeight);
            foreach (var dropInfo in spawner.Drop)
            {
                if (random < dropInfo.Chance)
                    return dropInfo.Item as GameItem;

                random -= dropInfo.Chance;
            }

            return null;
        }

        private static int CalculateTotalDropWeight(this Spawner spawner)
        {
            var allWeight = 0;
            foreach (var dropInfo in spawner.Drop)
                allWeight += dropInfo.Chance;

            return allWeight;
        }

        public static void TestDrop()
        {
            foreach (var spawner in DataEditor.MergeGame.Spawners)
            {
                Debug.LogWarning($"Testing Drop {spawner.Name} level {spawner.Level}");
                var drop = spawner.DropRandomItem();
                drop.PrintInfo();
            }
        }
    }
}

What's next

  1. Import the Merge template.
  2. Deploy the changes.
  3. Open the Unity project and generate the code.
  4. Add the files to your project to work with GameItem and Spawner, written above.
  5. Initialize Balancy.
  6. Add the following code in the callback.
GameItemExtension.PrintAllItems();
SpawnerExtension.TestDrop();