Tuesday, January 31, 2012

The Art Of The Fairy, Environment


Harry The Fairy is an 2d adventure, action, puzzle game for iPhone, iPad and Android.

To render the 2d graphics and help us make sprite atlases in unity3d, we used Sprite Manager 2 from http://www.anbsoft.com/.

This is a short run-through of how we did the environment graphics for the game.

The game is set in the caves under a forrest. Here our hero has to save his friends from the evil machines.
The idea was that the hero shouldn't feel at home in the caves, he is clearly out of his element.
The caves are meant to be frightening without being too scary.

We wanted the game to look hand-drawn more than 3d or realistic, so all the concepts and art pieces are painted in photoshop.

This early concept shows a dark and gloomy cave. Not many colors and a bit cold.

This captures the feeling we wanted pretty good and became the most importent concept drawing.
But before we could design the final pieces we had to decide on the shapes of the the walls.

We had to find some shapes that could shape the caves organically and overlap without it being to obvious, where they overlapped each other.

It looked great, but it was to dark and colorless.
We wanted to emphasize the difference between nature and the evil machines a bit more.
So the environment needed more color and the machines should stay almost colorless.
The machines used only one “warning” color, yellow.

We made the walls look more like earth/dirt, but still with some gray stones. We also made objects, such as roots, grass and mushrooms to use for decoration.


The focus was to make an organic environment, that looked natural and not made of boxes.
Each of our two walls had their own mesh collider, to make the interaction with the environment natural.


The deeper you go underground the more dangerous the environment gets. Here lava-walls were created from the same shape as the dirt-walls making it possible for us to use the same mesh colliders.


The machines were made of small parts put together to create wheels, levers, doors and hatches.


As a way to close off the cave from the parallax background, we used a dark piece of stonewall. This way we could make some areas seem like narrow tunnels and others like big open caves.



All these elements was build into two sprite atlases.

Finally we added a dark shadow mesh around the level to close off the cave.


I hope you found this useful, feel free to email me with questions.

/Bo


Wednesday, January 25, 2012

Nearing release of Harry the Fairy

So…the release candidate Harry the Fairy has been approved and has passed QA at Chillingo, so the release date is getting closer.

We've been working on/off on this title since medio 2010. The first 6 month or so, we mainly just had sporadic discussions on setting and gameplay, but no actual prototyping work was done since we were finalizing Angry Viking as well as doing tedious work-for-hire jobs - had to find a way to pay the bills. 

But when time allowed it, we did get some work done on Harry. When we got funding by the Nordic Game Program to do this game it was under the working title "You got Snail" and the gameplay was a mix of World of Goo, Angry Birds and The Incredible Machine. We did some prototyping and realized bit by bit that our design did not match the affordances and constraints of the smartphone platform. We killed a ton of darlings, and ended up with a "non-touch" tilt-gameplay. That design decision also caused a change in protagonist - from snail to fairy. 


We're really happy about the end result and hope you will like it to. If not, you have no taste…Thanks to Chillingo and producer Kieren Smith for the cooperation until now. At first we're releasing to iOS, but Android is on the roadmap.

Now fly Harry, fly

Monday, January 23, 2012

Reducing build size in Unity games

Creating games with Unity, having a large number of custom levels, while trying to get under that App Store and Android Market limit of 20mb? This is a problem we've faced a few times, and finally i've gotten around to look into creating a method to minimize the size of the final build by serializing the scenes and just instantiating prefabs at level load. We are currently working on a game which will more than likely have 100+ levels, and this method will help us cut down drastically on the final build size. The game has a one-button type gameplay and currently has the very ingenious working title “Rollers”.

The current version limits itself to instantiating prefabs that does not differ from the blueprint, although it should be a rather simple fix to do that, I just don't need it myself :)

You need to use JSONFX to complete this tutorial

In this example I have a number of worlds, each with a number of levels.


Each of these levels contains a number of walls (All instances of a wall prefab with the tag “Wall”)



Additionally the level has a gameobject called info with the following monobehaviour attached: Basically the only this here is we have the ability to mark each level with a specific world, not at all necessary for everybody, but I need it :)
using UnityEngine;
using System.Collections;

public class LevelInfo : MonoBehaviour
{
    public GameEnum.WorldEnum World;
}

public class GameEnum
{
    public enum WorldEnum
    {
        World1,
        World2,
        World3
    }

    public enum PrefabEnum
    {
        PrefabWalls
    }
}

The following script must be placed in a Assets/Editor folder, and adds a menuitem under Tools/CustomHelpers. It runs through the currently open scene, locates all prefabs with tag “Wall” and serializes the scene to a textasset which is placed in a corresponding folder.
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;

public class SerializeScene : ScriptableWizard
{
    public string Folder = "Levels";
    string assetPath;

    [UnityEditor.MenuItem("Tools/CustomHelpers/Serialize Scene")]
    static void SerializeOpenScene()
    {
        SerializeScene ss = (SerializeScene)ScriptableWizard.DisplayWizard("Serialize Scene", typeof(SerializeScene));
    }

    void OnWizardCreate()
    {
        //Find Levelinfo and extract info on which world the level belongs to
        LevelInfo li = FindObjectOfType(typeof(LevelInfo)) as LevelInfo;
        GameEnum.WorldEnum world = li.World;

        // Get the path we'll use to write our assets:
        assetPath = Application.dataPath + "/Resources/" + Folder + "/" + world.ToString() + "/";
        Debug.Log("Save at " + assetPath);

        // Create the folder that will hold our assets:
        Directory.CreateDirectory(assetPath);

        FindAssets();

        // Make sure the new assets are (re-)imported:
        AssetDatabase.Refresh();

    }

    private void FindAssets()
    {
        List<GameObject> objList = new List<GameObject>();

        LevelData newLevel = new LevelData();

        //Trim string to leave out folder information
        newLevel.Name = trimStringToSceneName(EditorApplication.currentScene);

        //Walls
        GameObject[] walls = GameObject.FindGameObjectsWithTag("Wall");
        Debug.Log("We found " + walls.Length + " walls");

        addObjects(walls, GameEnum.PrefabEnum.PrefabWalls, ref newLevel);

        string newObject = JsonFx.Json.JsonWriter.Serialize(newLevel);

        FileStream fs = new FileStream(assetPath + newLevel.Name + ".txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);
        sw.Write(newObject);
        sw.Close();
        fs.Close();

    }

    private void addObjects(GameObject[] objList, GameEnum.PrefabEnum prefabEnum, ref LevelData level)
    {
        for (int i = 0; i < objList.Length; ++i)
        {
            //Only look for instances of prefabs
            if (PrefabType.PrefabInstance == EditorUtility.GetPrefabType(objList[i]))
            {
                GameObject root = EditorUtility.FindPrefabRoot(objList[i]);

                //Only add to list if its the root to make sure the same object is not added several times
                if (root == objList[i])
                {
                    Debug.Log("It's the Root");
                    level.AddNewPrefab(objList[i], prefabEnum);
                }
                else
                {
                    Debug.Log("It's not the root, so we dont add it to list");
                }
            }
            else
            {
                Debug.Log("NOT A PREFAB");
            }
        }
    }

    private string trimStringToSceneName(string path)
    {
        string sceneName = string.Empty;

        //Removing all but levelname + ".unity"
        string tmpString = path.Remove(0, path.Length - 13);

        //removing ".unity"
        sceneName = tmpString.Substring(0, tmpString.Length - 6);

        return sceneName;
    }
}

You will need these classes as well:
using System.Collections.Generic;
using UnityEngine;

public class LevelData
{
    public string Name;
    public List<SpawnType> ObjectsToSpawn = new List<SpawnType>();

    public void AddNewPrefab(GameObject newObj, GameEnum.PrefabEnum prefabEnum)
    {
        Vector3 pos = newObj.transform.position;
        ObjectsToSpawn.Add(new SpawnType(prefabEnum, pos));
    }
}

public class SpawnType
{
    public GameEnum.PrefabEnum PrefabType;

    public float PosX;
    public float PosY;
    public float PosZ;

    public SpawnType()
    {
    }

    public SpawnType(GameEnum.PrefabEnum prefabEnum, Vector3 _transformVector)
    {
        PrefabType = prefabEnum;
        PosX = _transformVector.x;
        PosY = _transformVector.y;
        PosZ = _transformVector.z;
    }


    public Vector3 GetVector3()
    {
        return new Vector3(PosX, PosY, PosZ);
    }

}


Ok, so now we're able to serialize a scene, saving the type and location of prefabs, and tag it with the corresponding world. Now we need a scene which is able to deserialize the textassets and instantiate the prefabs. Create a new scene called LevelLoader, create an empty gameobject, name it “Loader” and give it the following LevelLoader script.



using UnityEngine;
using System.Collections;

public class LevelLoader : MonoBehaviour
{
    public TextAsset LevelToLoad;
    private LevelData levelData;
    // Use this for initialization
    void Start()
    {

        levelData = JsonFx.Json.JsonReader.Deserialize<LevelData>(LevelToLoad.text);
        Debug.Log("leveldata loaded from textasset and deserialized");

        initiateLevel();
    }

    private void initiateLevel()
    {
        GameObject wallParent = new GameObject();
        Transform walltransform = wallParent.transform;
        wallParent.name = "Walls";

        foreach (SpawnType go in levelData.ObjectsToSpawn)
        {
            //You need to have you Prefabs placed in a "Prefabs" folder
            string resourcePos = "Prefabs/" + go.PrefabType.ToString();
            Object objLoaded = Resources.Load(resourcePos);
            Vector3 pos = go.GetVector3();

            GameObject newObj = Instantiate(objLoaded, pos, Quaternion.identity) as GameObject;
            newObj.transform.parent = walltransform;
        }
    }
}
The above code creates an empty gameobject called walls to use as a parent for all the instantiated prefab, feel free to make this more dynamic. I'll do it myself at a later stage but for the time being it suits my needs. This should allow you to instantiate any number of levels by serializing them and then just include a single scene in your final build that can deserialize it and spawn the relevant gameobjects. Screenshot of the Leveloader scene with the instantiated prefabs:


Hope you found this helpful, although it's mainly a proof of concept. I'll make it more dynamic when I get around to it.

Here's an example: Unity Package

From deathmetal to fairydust

Creating games for the app store and getting them noticed can sometimes feel as trying to make your voice heard in a gym hall filled with screaming children. With more than 100k games to compete with, you need a high quality game, a keen eye on PR and a §#!^load of luck.

The load of luck seemed to be a bit hard to affect in any way, and getting a high quality game was just a matter of putting in the effort needed, but the PR was something we could affect.

The logical consequence for us was to enter a store filled with big brightly colored, non-challenging games featuring cuddly, big-eyed protagonists with a game about a featureless black & white viking on a murderous drug-induced rampage accompanied by the most aggressive death metal music south of the north pole and buckets and buckets of blood.

If we were going to go niche, we would be SO niche that we would basically need every last member of our target demographics to buy the game in order for it to be profitable, although we, in hindsight, might not have realized that fact from the start.



Angry Viking is the mutual lovechild of Bo and Jeppe and was released in June 2010. Although the quality of the game might have been somewhat lacking at the time, the niche approach seemed to yield an acceptable number of downloads. That number rather quickly plummeted though, it would seem that metalheads with an affinity for mindnumbing violence has quality demands as well...

At the time we released the game on Android we had drastically increased the quality of the game and got a lot better reception, even though Pay-Per-Download games seem to have a hard time on the Android Market. Our current version rating is 4+ on both iOS and Android, but the next time we're going for a niche market, we're going for 5% of a demographic instead of 0.1%.

In our current project we've shifted from blood, metal and vikings to a timid fairy named Harry. From 3D to 2D. From deathmetal to chimes and eerie classical music. From black, white and bloodred to earthcolors. Basically no similarities exist between the two games.



When cleaning up our project folders after Angry Viking was released we found a folder named “PR & Marketing” which was completely empty, that pretty much sums up our approach at the time - We would make the game and then just leave it to be discovered by its own devices, which is a faulty attitude at best...

We decided that we were no good at making ourselves noticed so we turned to Chillingo/EA to ask if they would be interested in working together on “Harry the Fairy” which they were. This leaves us with doing what we do best and love doing – making games.