Mechtronaut

Description

Mechtronaut is a project that I have done with my friend Tim and Wesley for Global Game Jam Groningen 2020. It is a 2D platformer with Game Boy style pixel art. You are going to be a mechanist inside a huge machine, and what you are facing is indescribable creatures that are trying to destroy and invade your machine. Of course, you are just a mechanist, not a superhero. There’s no way that you can fight against these terrible enemies. The only thing that you can do is get some components and patch the holes that they are making. And here comes the topic of this game jam – repairing. And as usual, I became the developer again, who also did some design work.

A 48Hours work

We spent the first evening on building the game concept. And eventually, we reached Mechtronaut. At the early stage of designing, we have 4 different components for patching different holes. But since the difficulty was too terrible and the time limit, we cut it down to 1. But you can still find those assets inside the art folder.

Main work that I have done is in the game scene, which is the difficulty system. The difficulty of the game raises over time, what I have done is basically made a machine that gets the passed time as input and increases the game difficulty as output.

Difficulty system

The difficulty controller manages the pace of the game. There is a float called “difficulty” that is in charge of the difficulty system. The time cost of a hole to become bigger, the chance of spawning a mob and etc., they are all related to this float. And to increase the difficulty to let your finger dance, this float will increase as the time goes. And finally, those variables that affect the difficulty directly will reach a max amount. How they are calculated is like this:

private void DifficultyAdder()
{
    difficulty += Time.deltaTime / 60;

    if (secondsPerStage >= 4)
    {
        secondsPerStage = secondsPerStageBase - 2 * (difficulty - 1);
    }

    if (chanceOfSpawningMobs <= 0.85f)
    {
        chanceOfSpawningMobs = chanceOfSpawningMobsBase + chancePara * (difficulty - 1);
    }
}

secondsPerStage is a variable that controls the time of the stage of holes. There are five stages for one hole, and when a hole reaches the final stage, it tries to generate mobs.

private void stageCounting()
{
    if (stage < 5)
    {
        if (stageCounter < secondsPerStage)
        {
            stageCounter += Time.deltaTime;
        }
        else
        {
            stageCounter = 0;
            stage++;
            if (stage == 5){
                audio.playSoundClipOneShot(6);
            } else  {
                audio.playSoundClipOneShot(7);
            }
            
            RefreshStage();
        }
    }
}

Another variable below is, obviously, the chance of spawning a mob. This coroutine is called in the update method, so it runs every frame.

IEnumerator SpawningMobs()
{
    if(stage < 5)
    {

    }
    else
    {
        RandomNum = UnityEngine.Random.Range(0f, 1f);
        if(RandomNum <= spawningChance)
        {
            //Spawning Mob
            // print("Mob spawned, chance was " + RandomNum);
            obj = Instantiate(enemy, gameObject.transform.position, Quaternion.identity);
            obj.GetComponent<AIDestinationSetter>().target = player;
        }
    }

    yield return new WaitForSeconds(secPerSpawningTry);

    StartCoroutine(SpawningMobs());

}

In the inspector of [DifficultyController], you can see an array called [Item List]. It has a size of 4, which is for the 4 components we had at the beginning.

When a hole is patched, or in terms of programmers’ languages: when the component’s collider collides with the hole’s, it will loop through the array of required items to see if it really needs this to fix the hole. And if there’s nothing needed anymore, then destroy this and make a new hole. It’s achieved like this:

private void OnTriggerEnter2D(Collider2D collision)
{
    if(collision.GetComponent<ItemObject>())
    {
        if (requiredItems.Contains(collision.GetComponent<ItemObject>().GetItemData()))
        {
            requiredItems.Remove(collision.GetComponent<ItemObject>().GetItemData());
        }

        if (requiredItems.Count <= 0)   
        {
            score.addToScore(1);
            collision.GetComponent<ItemObject>().SelfDestruction();
            FindObjectOfType<DifficultyController>().SpawnNewWall(transform);
            Destroy(this.gameObject);
        }
    }
}
public void SpawnNewWall(Transform t)
{
    Instantiate(prefab, t.position, Quaternion.identity);
    prefab.GetComponent<ThingsToRepair>().SetCounterTo(-UnityEngine.Random.Range(secBetween.x, secBetween.y));
}

This is a life cycle of a hole. You can see lots of remnants from our earlier design. We even had an idea of randomly generated holes, but we didn’t manage to do it since I couldn’t find an elegant and doable solution in that limited time.

In folder [Scripts/Sean’sCode], you can find all the codes that were written by me. Although some are edited by Wesley, he used this project for a college course later, but the difficulty controller, the interaction between objects, holes and components (those boxes that you can lift) were my work.

Sound design

And you might notice that this game is juicier than my other games. That’s because we have some sound effects and background music! And of course, that’s my masterpiece! I was even prouder than ever before because I realized that adding some sound effect has so much contribution to the game. I used Bfxr for creating 8 bit sound effect and LMMP plus Magical 8bit plug for the melody. I could’ve made some variations for the melody in different stages of the game if I had more time. For example: increase the pace and tune of the original one if there are mobs in the game world to pass a tension to the player. This was the first time that I work on sound and music for a project, and I think it’s really cool. I just need to learn more about these so I can make my game even juicier in the future.

Oh, if you can’t wait to take a listen before you play the game, here’s something for you.

Download

You can get the Unity project/source code here on GitHub repository or download the build on this page.

But please note, the commits after the GGJG(2nd Feb 2020) were done by Wesley(TeraBitGaming). As I know, he added a tutorial and optimized the interaction with boxes (components that for patching holes).

Please pull from the [master] branch.

Recommended Unity version: 2019.3.0f6

Open the scene called [StartScene] in [Scenes] folder for demonstration in Unity Editor/Run the executable file called [Global Gamejam 2020 – Robot Game] to run the demo build.

Reference

Bfxr. Make sound effects for your games. Retrieved from https://www.bfxr.net/

LMMS | Home Retrieved from https://lmms.io/

Magical 8bit Plug | YMCK Official Site Retrieved from http://ymck.net/app/magical-8bit-plug/ (Japanese site)