Building a Minigame Manager: Lessons from My (almost) First Game Jam


Hi everyone,

First of all, Balance Behind Bars is the first real game I've ever developed. I had made a few prototypes before while working through Unity Learn courses, but this is the first project that I can truly consider a "game."

Because of that, what you’ll see here may not be "the best solution" — or even "an optimal one" — but I'm really proud of what I achieved, and that's why I'd like to share it with you.

This game was created for the GameDev.js Jam 2025, whose main theme was "Balance". 

The best idea that came to my mind was to create a system where you could earn or lose points based on your actions, and your surroundings would react according to your score. That's how I ended up designing a prison game.

In this setting, prisoners will respect you if you behave badly enough, but will envy you if you behave too well. Meanwhile, the guards will react in the opposite way. Of course, if you want to eventually escape the prison, you'll need to build up a lot of positive reputation.

With this idea in mind, I thought about creating a minigame system, where each day you would be assigned a couple of prison duties — and it would be up to you whether you chose to complete them or not.

And that leads to the key question: How do you manage a task system effectively?

I thought about three different types of minigames:

  • In the first, randomly placed objects appear, and the player must walk through them to collect them.
  • In the second, a pop-up window prompts the player to follow a sequence of instructions.
  • In the third, the player must find a specific location, pick up an item, and deliver it to a hidden character.

Each task is displayed in a task list, with an indicator placed at the minigame's starting location. To make navigation easier, the indicator's color matches the color of the corresponding task text

Although it might sound simple (and honestly, there’s probably a much easier way to do it), I initially struggled a lot trying to create a general system that could handle different kinds of tasks.

That’s when I learned about interfaces.

In simple terms, an interface is like an incomplete class — you define some methods, and any class that implements the interface must provide its own version of those methods.

This turned out to be super useful. I was able to create an ITask interface with Start, CheckCompletion, and Finish methods, and then build a manager that spawns a random set of tasks each day:

public interface ITask
{
    // In all the game object we must define a method to start the task
    void StartTask();
    // A method to check if the task is over
    bool CheckCompletion();
    // And a method to destroy the task
    void FinishTask();
}

Thanks to the interface, I created a "GeneralTask" class that the TaskManager can use to manage any kind of task.

Each task still has its own script (because they all behave differently), but since they all implement ITask, the GeneralTask class can interact with all of them in the same way.

During initialization, the GeneralTask checks the task's name, links to the correct script, and sets up the corresponding UI elements like task text and indicator color:

public void InitTask()
    {
        // Depending on the task we enable different things
        switch (this.taskName)
        {
            // Clean the yard
            case "CleanYard":
            {
                // Take the game object
                taskGO = GameObject.Find("TaskController/CleanYardTask"); 
                
                // Set the target position
                target = new Vector3(-12, -10, 0);
                
                // Add the task to the list
                taskText.transform.Find("Text").gameObject.GetComponent<TMP_Text>().text = "Clean prison yard\n";
                break;
            }
            // Clean the bathroom
            case "CleanBathroom":
            {
                // Take the game object
                taskGO = GameObject.Find("TaskController/CleanBathroomTask"); 
                
                // Set the target position
                target = new Vector3(3.5f, 16, 0);
                
                // Add the task to the list
                taskText.transform.Find("Text").gameObject.GetComponent<TMP_Text>().text = "Unclog the toilet\n";
                break;
            }
            ...
        }
        // Paint the dot in the task list
        taskText.transform.Find("Image").gameObject.GetComponent<Image>().color = IndicatorColor;
        
        // At last we set the indicator
        Indicator.GetComponent<IndicatorScript>().ChangeColor(IndicatorColor);
        Indicator.GetComponent<IndicatorScript>().SetTarget(target);
        Indicator.GetComponent<IndicatorScript>().HideCursor(false);
        
        // And start the task
        taskScript = taskGO.GetComponent<ITask>();
        taskScript.StartTask();
    }
    public bool TaskComplete()
    {
        taskComplete = taskScript.CheckCompletion();
        ...        
    }
    public void FinishTask()
    {
        taskScript.FinishTask();
        ...
    }

At the end, I created a "TaskManager" that, at the start of each in-game day, generates a list with N different tasks.

Thanks to the common structure provided by the interface, I didn't have to worry about each task having a different script — the TaskManager could handle all of them in the same way.

taskClasses.Add(new TaskClass(TaskName: task, TaskText: taskTexList[index], Indicator: indicatorsList[index], IndicatorColor: taskColorsList[index]));

This was the best approach I found to manage different kinds of minigames that could be activated randomly within a single game.

You can check out the full code on my GitHub!

If you have any questions, feedback, or suggestions for better implementations, please don't hesitate to leave a comment — I'd be really happy to discuss or learn more.

Thanks a lot for reading! ^^
See you!

Files

BalanceBehindBars.zip Play in browser
3 days ago

Leave a comment

Log in with itch.io to leave a comment.