Spores of Malice

Spores of Malice was made in C++ and is a bullet hell game, inspired by Enter the Gungeon.

Trailer: Spores of Malice

Details
  • Genre: Top Down Adventure, Bullet hell
  • Engine: The Game Engine
  • Duration: 7 weeks at 50%
  • Team: 6 programmers, 4 artists, 3 level design
My contributions for this project:
  • Dialog system
  • Destructible objects
  • Double buffered rendering
  • Particle system in both 2D and 3D
  • Scripted boss event

Dialog System

This dialog system works together with Unity. It was created for our level designers to be able to place box colliders in Unity to trigger the corresponding text. The text is read from a .json file 

Dialog triggered when entering the room

Loading the text from .json file was done by code below.

if (std::filesystem::exists(aFilePath))
{
	nlohmann::json jsonData = nlohmann::json::parse(file);
	file.close();
	std::vector<std::string> tempStringHolder;
	for (int i = 0; i < jsonData["Text"].size(); i++)
	{
		for (int j = 0; j < jsonData["Text"][i]["value"].size(); j++)
		{
			tempStringHolder.push_back(jsonData["Text"][i]["value"][j]);
		}
		myMap[jsonData["Text"][i]["id"]] = tempStringHolder;
		tempStringHolder = {};
	}
}

Text example of the .json file

"Text": [
  {
    "id": 0,
    "value": [
      "Bob: Ohh my shroom, why can't I move?!",
      "Nettlerot: You can't move because I am in control.\nNow, how did these controls work?",
      "Nettlerot: aah yes, just like a keyboard and mouse,\nthe WASD keys move this shroom around."
    ]
  },
  {
    "id": 1,
    "value": [
      "Bob: BENNY HELP ME! I am being\ncontrolled by an evil gun demon!",
      "Benny: Bob is that you? My senses\nreally aren't what they used to be.",
      "Nettlerot: Ahh Benny, the first in a long line of victims before my power.",
      "Nettlerot: Now how can I make this\nshroom guy pull my trigger...?",
      "Nettlerot: Of course, I use the mouse to aim him,\n then the LEFT MOUSE BUTTON to fire!",
      "Nettlerot: I need to thank the gamer\ndemons for this later, HA HA HA HA"
    ]
  },

Destructible objects

To create more fun interactions I added particle effects on the destructible objects.
I find the destructible objects to be the ideal amount of interference. In tense situations, it's hardly noticeable, but when I intentionally interact with it, it feels deeply satisfying.

Displaying destructible objects

Update loop for Destructible objects

bool Destructible::Update(float aDeltaTime, Tga::Vector3f aPlayerPos, BoxCollider aPlayerCollider)
{
	float distToPlayer = (aPlayerPos - myTransform.GetPosition()).LengthSqr();
	if (distToPlayer > myRadiusSquared)
	{
		return false;
	}

	if (myIsDead == true)
	{
		myDeadTimer += aDeltaTime;
	}

	if(myBoxCollider.CheckCollision(aPlayerCollider) == true)
	{
		for (int i = 0; i < myAllParticleSystems.size(); i++)
		{
			myAllParticleSystems[i]->Play(true);
			if (myIsDead == false)
			{
				PlayDestroySound();
			}
		}
		myIsDead = true;
	}

	if (CheckBulletCollisions() == true)
	{
		myIsDead = true;
		return false;
	}
	return true;
}

Double buffered rendering

Main loop and logic thread creation.

// Logic Thread
std::thread logicThread(&CallUpdate, &gameWorld);
// Main loop
while (engine.BeginFrame())
{
	syncDone = true;
	gameWorld.Render();

	while (!gameReady); // Wait for UpdateLoop

	engine.EndFrame();
	input.Update();
	controllerInput.Refresh();

	gameReady = false;
	if (gameWorld.GameShouldQuit())
	{
		break;
	}
}

logicThread.join();

Logic thread loop

void CallUpdate(GameWorld* aGameWorld)
{
	Tga::Engine& engine = *Tga::Engine::GetInstance();
	while (globalMessage != WM_NCDESTROY)
	{
		if (syncDone == true)
		{
			syncDone = false;
			DoControllerInput();
			aGameWorld->Update(engine.GetDeltaTime());
			gameReady = true;
		}
		if (aGameWorld->GameShouldQuit())
		{
			break;
		}
	}
}

Particle System

I created a particle system for the previous project and wanted to keep developing the tool as it created a better mood for the game. The system was previously only 2D but for this game I developed it to become both 2D and 3D. 

Using 5 combined particle systems to create falling leaves

The particle system is something I have been working on during most of the game projects at school and is something I am very proud of.

To get a more in depth explanation about the particle system click the link below.
Read more

Scripted boss event

I created a simple scripted event to distinguish boss fights from normal enemy fights. When entering a boss room the moment is locked and camera pans to the boss that falls down from the sky.