Island Game

OVERVIEW

A 2D survival game in which the main character is marooned on a deserted island. The player will hunt, forage, and craft as increasing stamina and resources allow them to explore farther and farther away from a home base.

CORE GAMEPLAY

The game centers around managing four statistics:

  • Hunger 

    • Depletes over time

    • Restored by eating

  • Thirst

    • Depletes over time

    • Restored by drinking

  • Stamina

    • Depletes with player movement or actions

    • Restored by sleeping

  • Health

    • Depletes immediately when attacked

    • Depletes over time when any other stat reaches 0%

    • Replenished with specialty items

    • Game ends when health reaches 0%

ABOUT THE PROJECT

Because not all team members had Unity experience, my main focus was to make tools that were accessible to a person who has never used the Unity game engine before.

PLATFORM

  • Windows

SOFTWARE

  • Unity (C# scripting)

  • Aseprite

MY ROLE

TEAM

In addition to myself, the team included:

  • A programmer who developed player movement

  • A pixel artist/writer who designed the character

  • Two game designers who would craft the levels, determine numbers for the stats, and design items and their effects on the character

SCRIPTABLE OBJECTS

I designed a way to create objects using Unity's ScriptableObject class. These objects are meant to store data on the items that appear in the game. Scriptable objects are easy to implement and allow developers to make game objects directly in the Unity editor without typing any code.

TASK

Each food item needs to remember important data about itself:

  1. Text names and descriptions that will be displayed to the player in a menu screen

  2. Whether the item has been found by the player already - if not, a special animation, sound, or graphic can be used to reward the player for exploration

  3. Stat restore values that indicate how player statistics are affected when the item is consumed. For example, a coconut might restore the hunger and thirst stat, while a coffee bean might provide a boost to stamina

  4. A sprite (image file) of the item is also required in order for it to be displayed in-game

IMPLEMENTATION

Because there will be many items in the game, but not all of them will be consumable, I created a class called ScriptableItem that inherits ScriptableObject. This class contains variables that are common to all items, but not food, including:

  • string itemName

  • string description

  • bool isFound

  • Sprite iconSprite

  • Sprite iconPortrait

I then wrote a ScriptableFood class that inherits ScriptableItem. This class contains the characteristics specific to consumable items:

  • int foodID

  • int[] statGain

ScriptableFood ​also contains an ApplyStatGain method that affects the player's stats based on the values in the statGain array, which contains effects in alphabetical order: health, hunger, stamina, and thirst.

Clam Item.png
Conch Item.png

Scriptable objects can be made through the Unity hierarchy (above). Details of the items can be set by developers in the Unity inspector (right).

The core loop involving losing and regaining stat values is demonstrated in the video. The player loses hunger and thirst over time. Items can be picked up and eaten to restore these values. The features seen in the video are implemented using the scriptable object system described above.

A collaborator designed and drew the playable character, while I made the environment tiles, objects, and HUD using Aseprite.

 

TILE EDITOR

I explored Unity's TileMap workflow to create tiling tools that other developers could use to map out levels. Using these templates, special tiles can be made that animate frames in different ways. I also use tiles as collision objects that keep the player within the bounds of the scene.

TASK

Not all animated tiles are created equal. The ocean tiles represent three different types of animating frames by code: sequential, random-start sequential, and random.

Waves on the shore are an example of sequential tiles, where waves must animate at the same rate in order to appear believable. These tiles must start on the same frame and progress through the next frames at a unified rate.

The transition from the shallow beach to the deeper ocean are made up of random tiles, where the next frame is randomly selected from the set of all frames. Unlike the shore waves, these transition tiles look most believable when they are not matched up with each other.

The last type of tile, random-start sequential, is required for the deep ocean ripple tile. Because the motion of the wave moves from left to right, each frame shown must be played sequentially for the animation to make sense. However, if the ripples all begin and end at exactly the same time, they can look too synchronized with each other. By randomizing the index of the starting frame, the ripples can achieve a more natural feel.

Collaborators can quickly design scenes using pre-made tiles in the tile palette.

Beach Palette CU.png
Beach Palette CU.png
Beach Palette CU.png
Beach Palette CU.png

Pixel art assets that I created using Aseprite were sliced in Unity to create a tile palette.

IMPLEMENTATION

The tile features are relatively new, so the developers have posted samples that I referenced to create my own tiles. I based my code off of Janis Simson's AnimatedTile script.

Tiles that inherit Unity's TileBase class will automatically recognize any Sprite array stored into the tileAnimationData.animatedSprites reference parameter of the GetTileAnimationData method as the tile's set of animation frames. As the tile cycles through the frames in order at a set speed, the script can be used in its original form for the waves that crash on the shore. The script also contains code that creates a custom editor for the tile in Unity's inspector.

A developer would use this coded feature by creating an AnimatedTile asset in the Unity editor, then modifying it in the inspector menu.

The custom inspector menu created by the AnimatedTile.cs script.

Animated Wave Tile.png

For the random and random-start sequential tiles, I needed to rearrange the contents of the sprite array before it was loaded into the tile animation data. To do this, I created Reshuffle and RandomizeStart methods, as well as checkbox booleans for a developer to indicate that a selected feature should be applied to the tile. 

Reshuffle Code.PNG

The Reshuffle method iterates through the array and flips each frame with another at a random index.

RandomizeStart.PNG

The RandomizeStart method chooses a random frame to be the new starting index, and copies sprites from the original into a new array accordingly.

Animated Transition Tile.png

After the sprites are loaded, selecting the "Reshuffle" box will randomize the animation order.

Animated Bubble Tile.png

Selecting the "Randomize Start" box will choose a new sprite as the starting frame.

My goal in creating this workflow was that collaborators who are not experienced with Unity can quickly and easily set animated tiles and their properties without having to code. Rather than create multiple animation variations in the form of many different tiles, the scripts automatically randomize the animations. Additionally, if a change needs to be made to the animated tile, only one adjustment has to be made in the editor, rather than many across multiple hard-coded sprite sets. The coded tiles achieve a naturally randomized feel within the game's environment. They are flexible and can be used to create other effects.

The shore waves at the top animate sequentially, the shallow to deep transition waves in the middle animate randomly, and the deep ripple waves at the bottom animate random-start sequentially.

 

©2020 by Erica Koplitz