Zomb-E

Zomb-E is a first person shooter game based on the "Zombies" game mode from the Call of Duty series. It was made in our own engine, "Penugine", which we developed during the previous semester at The Game Assembly.

Scope: fifteen weeks at twenty hours per week.

GIFs are generally clickable to show a higher resolution mp4 file.


As with our previous project, Spite, I handled the programming side of UI work on Zomb-E. Because most of the work had already been implemented, the menus and HUD could largely be copied over with small changes where necessary, and updated with new assets as they were finshed by our graphical artists.

My early work on Zomb-E involved setting up a framework for spawning robots (our equivalent of the zombie enemies) and a general gameplay flow which made sure the waves advanced properly, and that the player's objectives in the game functioned correctly.

Early version of spawning in enemies dynamically in the level.

Unlike Spite, the HUD in Zomb-E also made more use of text when displaying e.g. ammo count or currency, as they needed to be updated dynamically with game parameters, which gave more opportunity to make sure the text class functioned well and worked with different font formats.

A rough implementation of the game objectives with some descriptive text and an "ending" to the game.

When not working on UI, I was also responsible for setting up the player's animation system and tying it to our sound system, Wwise. Additionally I was in charge of importing sound in our game (due to the lack of dedicated sound designers), which unfortunately mostly involved browsing the sound bank provided to us by TGA, with little actual programming work.

Early implementation of player animations and sounds.

As we used a single generic model for the player's arms with the guns attached to a specific bone, some work had to be put in to ensure they positioned and rotated correctly according to the player's current animation.

Most of the work, however, was spent on making sure the player (and by extension their animations) transitioned correctly between different states. For example, you probably don't want the player to be able to reload while already firing, or using the wrong animation if shooting while running.

Some of the shooting animations, such as the one for our "machine gun" type of weapon were also more suited to be looping while others were not, which meant they had to be handled a bit differently when deciding to switch state.

case PlayerState::P_State_Shooting:
{
	if (gun->GetType() == eGunType::Rifle || gun->GetType() == eGunType::Laser)
	{
		myCurrentAnimation->Update(aDeltaTime);
		if (myInput->GetKeyUp(VK_LBUTTON))
		{
			myCurrentState = PlayerState::P_State_Idle;
			CheckStates();
		}
	}

	else
	{
		myCurrentAnimation->Update(aDeltaTime);
		if (myCurrentAnimation->GetState() == AnimationState::Finished)
		{
			myCurrentState = PlayerState::P_State_Idle;
			CheckStates();
		}
	}
	break;
}
More WIP of animations and sounds.

One of our courses at TGA was a Tools course where we were tasked with creating a tool, optionally as part of our game projects and/or engine, with a clear application and usage area in mind.

As we didn't have our own editor for Penugine and instead relied in Unity, there were sometimes concerns of whether models, sprites, effects, etc. would look correct when ported over to our engine. Ideally the files used in either program would be identical, but mistakes or oversights would naturally happen while working on our game projects.

To that end, I chose to create a model viewer for Penugine that used the same rendering system as Spite and Zomb-E, but without any of the gameplay code attached. The idea was that it would be faster to launch and simpler to use than loading up the game itself to check on any assets, and serve as a form of QA when our graphical artists were porting over finished models to our game.

Spoiler: this model was not oversized in Unity's editor.
Modelviewer with an animated model loaded, along with controls for the model, postprocessing, and lighting features.

The Modelviewer served its purpose quite well, and also proved useful as a quick way to bug fix and interate on our implementation of ambient occlusion and other graphical features. It will likely be updated with more features such as a scale reference and a bone listing in the future.

It also includes the option of loading a level file (JSON in our case), to check that a level made by our level designers is rendering correctly with everything in its correct place.

One of our Spite levels and some PH scenes being viewed in the modelviewer.