Click for content!

What I Created

Since I am the only programmer on Wellness Hero, I was in charge of all gameplay systems and tools to expedite development. I created systems including but not limited to:

  • Menus with Editor Debugs
  • TSV Reader
  • Mobile Player Input
  • Save System with Editor Debugs
  • Hooked up Unity Analytics
  • All Gameplay Mechanics
  • Main Menu
  • SFX and VFX implementations

Be your own Wellness Hero!

Wellness Hero is an app that aims to gamify the management of your mental health. It started as a paper prototype, which eventually evolved into an idea for something that people could carry around in their pockets.

Based on the “Spoon Theory” which can be explained as a metaphor for a persons limited energy levels throughout the day. These “spoons” represent energy and the limited number of spoons means that they must be rationed to make it through the day. Daily tasks have a “spoon” requirement, which explains how much energy it takes to complete that task. These tasks can range from small things like “making the bed” or “eating breakfast” to larger things like “working 9-5” or “fixing the car” to even larger and more abstract things like “dealing with a loss” or “suffering from anxiety.”

Click for content!

Energy Transfering

Towers are the core of Wellness Hero, and the main gameplay comes from determing how to connect and transfer your energy for the day. This energy transfer is slightly more complicated that I originally thought it was going to be, because connections can be created and destroyed at will. This means that energy needs to be recalculated on the fly based on what is currently connected to it. I knew I did not want to run this in update (which would have been the easy solution) and instead recalculate only when necessary.

There are a few different categories of energy, so I threw those into an array and was able to recalculate whenever a connection was created or destroyed through a single function which called the next tower in line.

Recalculating Energy


 // Calculate our used and extra energy.
public void CalculateUsedEnergy()
{
	// Add our default and supplied energies together.
	float[] totalEnergy = {defaultEnergy[0] + suppliedEnergy[0], defaultEnergy[1] + suppliedEnergy[1], 
							defaultEnergy[2] + suppliedEnergy[2], defaultEnergy[3] + suppliedEnergy[3]};

	//print("Total Energy: " + totalEnergy[3]);
	// Start from the top and subtract our cost if we have one. Return our remaining energy.
 	extraEnergy = CalculateExtraEnergy(totalEnergy);

	// Set our used values appropriately.
	//print("Total Energy: " + totalEnergy[3]);
	usedEnergy = new float[4] {totalEnergy[0] - extraEnergy[0], totalEnergy[1] - extraEnergy[1], 
								totalEnergy[2] - extraEnergy[2], totalEnergy[3] - extraEnergy[3]};

	totalUsedEnergy = usedEnergy[0] + usedEnergy[1] + usedEnergy[2] + usedEnergy[3];

	// Call this for our next tower if we have one and supply our extra energy.
	if(lPoint.GetNextLink() != null)
	{
		lPoint.GetNextLink().GetTower().SetSuppliedEnergy(extraEnergy);
	}

	// Update graphics because we have new energy values.
	UpdateGraphics();
}
					

TSV Reader

Something that I have programmed that is unique to Wellness Hero is a TSV reader. We use a large excel sheet and instead of a CSV (comma separated values) we use a TSV (tab separated values) document. This was fun to program and was one of the first times I had to read an outside document in C# for a game.

To help with debugging, I created buttons in the Unity inspector that can be used to read the TSV at any time and generate a list of cards from it. Being able to regenerate all of these cards (100+) on the fly was crucial to developing and tweaking values to balance the game.

Parsing Values from the TSV


// Create a new journey.
Intervention thisJourney = ScriptableObject.CreateInstance<Intervention>();

// Fill in the cards values.
thisJourney.Name = values[2];
thisJourney.Description = values[13];
thisJourney.Type = values[6];
thisJourney.Path = values[7];
float.TryParse(values[9], out thisJourney.Cost);

if(values[8] != "")
{
	thisJourney.Awareness = values[8].ToCharArray()[0];
}
            
float.TryParse(values[10], out thisJourney.Power);
int.TryParse(values[1], out thisJourney.FrequencyWeight);
int.TryParse(values[0], out thisJourney.Id);
					

Creating a new Card


#if UNITY_EDITOR
// Add the card to the folder.
string thisJourneyPath = interventionPath + thisJourney.Name + ".asset";
AssetDatabase.CreateAsset(thisJourney, thisJourneyPath);
#endif

// Add to card list.
bManager.AddToInterventionLists(thisJourney);

// Add to skill tree.
skillTreeManager.AddCardToSkillTree(thisJourney);
					

Analytics

This was my first time using any sort of analytics for a game. I started with Google Firebase, however migrated to Unity Analytics when we upgraded the project to Unity 6 last December. Organizing events to determine user retention and contention points was a new experience that led me to learn more about how to keep a player playing.

This is from our in-house playtesting, displayed on the Unity Cloud website.

Click for content!

Save Manager

Wellness Hero is an endeavor that I joined after my experience with Linn Falls, so I was already experienced with saving for mobile devices. Where Wellness Hero differs is how much information is saved. There are a lot of things to keep track of: player level, the interventions they have integrated (saved), the level of each intervention category, the placement and information regarding the towers on the field, etc. Each script that needs something saved has a unique class and a Save function that can be called from a central SaveManager that collects and exports everything into a JSON file to load for the next play session.

Save Manager collecting Data


// Collect and save our data!
public void SaveData()
{
	// Start collecting our data.
	SaveData allData = new SaveData
	{
		EXPERIENCEDATA = experienceManager.Save(),
		INTEGRATIONDATA = integrationManager.Save(),
		INVENTORYDATA = inventoryManager.Save(),
		DEPRESSIONDATA = depressionManager.Save(),
		WEEKLYDATA = weekManager.Save(),
		ROMANTICDATA = romanticTower.Save(),
		SUPPORTDATA = supportTower.Save(),
		TOWERDATA = towerManager.Save(),
		WINDATA = winManager.Save(),
		TUTORIALDATA = tutorialManager.Save()
	};

	// Save to file.
	string json = JsonConvert.SerializeObject(allData, Formatting.Indented);
	File.WriteAllText(filePath, json);
	print("Data saved.");
}
					

Saving our Placed Event Towers


// Gets our save data.
public TowerData Save()
{
	// Create an array storing our active event towers.
	EventData[] towersToSave = new EventData[eventTowers.Count];

	// Loop through our eventTowers and add to array.
	for(int i=0; i<towersToSave.Length; i++)
	{
		EventData newTower = new EventData
		{
			XPOS = eventTowers[i].transform.position.x,
			YPOS = eventTowers[i].transform.position.y,
			ZPOS = eventTowers[i].transform.position.z,
			THISEVENT = eventTowers[i].GetComponent<EventTower>().GetEvent(),
			TOTALCOST = eventTowers[i].GetComponent<EventTower>().GetTotalCost()
		};

		towersToSave[i] = newTower;
	}

	TowerData data = new TowerData
	{
		TOWERS = towersToSave
	};

	return data;
}
					

Debugs

Again, on the topic of making everyones lives easier, I was able to hook up some buttons to save and erase data from the editor. This has also saved up a lot of time testing and I thought it was worth noting.

Wellness Hero (WIP)

Lead Programmer

Ensemble Interactive

January 2024 - present

Skills: Mobile Development/Publishing, Dynamic Resolutions, Analytics, iOS, Android, C#