Calcium Overdrive
Summary
Calcium Overdrive is a fast paced, first-person, hack and slash platformer. In Calcium Overdrive the player competes against themself to beat levels as quickly as possible and while killing as many enemies as possible. This simple concept took a team of four game designers and one developer four months to bring to a vertical slice state. Throughout the development process I filled the roles of systems designer, UI designer, and producer. In the following sections I will detail core systems that I designed, the problems that I encountered, how I overcame them, and the end result that I achieved.
Systems Design
Weapon and Attack System
Our initial implementation of the weapon and attack system had a lot of issues. It was built entirely in a single weapon, relied on the weapon collision to register hits. This presented a lot of issues with hits feeling inconsistent and even after a significant amount of animation work, aiming attacks up or down was functionally impossible. So four weeks into the project I started refactoring the system with the following requirements:
The system must use traces to register hits
It must be easy to make weapons with different models and stats
Weapons must be able to have a special ability that can be triggered with a right click.
Obstacles
This system did not present many obstacles other than figuring out where to have the logic for attacks stored, but using blueprint components and proper use of inheritance made this a relatively easy system to implement, with the biggest challenge being that the system was time intensive and I had to stay on top of other deliverables while building the system and not breaking anything while it was in progress to avoid inhibiting my teammates’ progress.
Implementation
The final implementation I landed on has three primary components:
A base weapon from which children can derive variables for attack damage, range, speed, radius, attack animation set, projectile type, and weapon mesh.
A base projectile from which children can derive variables for damage, range, speed, mana cost, and particle effects.
An blueprint component implemented on the player that uses all variables from the currently equipped weapon to create a multi-sphere trace to apply damage to enemies.
Scoring System
One of the tasks I took on early in the development cycle was creating a scoring system. The scoring system had to accomplish the following:
It must track completion time, and per-run kill count on a per level basis.
It must have medal rewards (mithril, gold, silver, bronze) that can easily be set on a per level basis.
The medals must reward time and kills separately.
The scores must be saved across gaming sessions.
Obstacles
I had never worked with any sort of scoring system, or even saving data between game sessions before this project.
I was unable to find applicable tutorials on YouTube.
Implementation
The solution I created consisted of four main components:
Structs for each level with variables for target times for all medals, kill counts for all medals, and player best performance for both metrics. Separate instances of these structs are saved in the game instance so that they can be modified and saved across play sessions.
A blueprint component implemented on the player character that does the following.
Converts the current level name to a string and checks which index in an array of level names matches the current level.
Takes the level index to pull in all scoring values from the appropriate struct from the game instance.
Times the player, and compares scores at the end of the level to the medal values and previous bests to award a medal.
A blueprint component on enemies that communicates via a blueprint interface to increment the kill counter for the player.
UI Design
Original Implementation
The original implementation of the UI for calcium overdrive was functional, but very poorly implemented. The key issues with my initial design were as follows:
There were a half-dozen blueprints that controlled widgets.
Widgets were constantly being created and destroyed in memory resulting in poor performance in menus.
I did not use base widgets for elements that were used in multiple place, instead opting to recreate certain elements in several widgets.
There was a ton of redundant code, especially for the various places that medals were displayed.
Goals for Final Implementation
As the team neared the midpoint of the project, I began the process of digging into the Unreal documentation to learn more about UI best practices and optimization. My goals for a final UI implementation were as follows:
The UI should be centrally controlled
It must be easy to add additional elements, especially level select tiles for the level selection menu.
It must be as performance friendly as possible.
Execution
To achieve these goals I implemented the following:
I centralized control of UI elements within two HUD classes, one for the main menu, and one for during and between levels. The HUD class controlling the UI was determined by a main menu game mode, and a gameplay game mode respectively.
I boiled menus down to a few core elements that could be used in various applications for displaying scores, buttons etc. and made parent widgets that I added to the various menus.
I created a macro library and a single macro that could handle displaying medals.
UI Feedback and Playtesting Issues
During playtesting I received feedback on menus and the HUD, as well as observed some areas where information was not effectively communicated to players. The main weaknesses from observation and feedback were as follows:
The original HUD had the health and mana at the bottom right and left corners respectively, and because of the fast paced nature of the game, players often lost track of their health and mana or forgot about them entirely.
I originally used a timer by event node for the level timer, which produced an inaccurate time, made worse by less powerful hardware.
Some elements had issues with legibility depending on the scene.
Tutorialization was severely lacking, with the controls menu being the only way to learn how to play the game.
I approached the UI rework with these issues in mind and addressed each issue as follows:
Moved the health and mana bars to the bottom center of the screen which allowed players to more effectively track their HP and mana as well as made the HUD feel less cluttered.
Moved the level timer from a timer by event to a delta time tick event which fixed timer inaccuracy and made the timer hardware agnostic.
Added backgrounds to previously illegible elements, as well as drop shadows to the text to ensure better legibility.
Created a base tutorial widget and recorded several tutorials for complex mechanics, and made an on-screen hint system for simple mechanics.
Final Results
Other Mechanics and Contributions
Grapple Mechanic (Tether Jump)
During the second month of the project, I added a grappling hook mechanic, in which you can target specific grapple points, press the appropriate input, a physics impulse is applied to the player avatar in the direction of the grapple point.
During Playtesting this mechanic I encountered the following issues:
The name of the mechanic caused confusion and players expected the grapple to behave more like the Batman Arkham Games.
The cooldown between grapples was too long and made timing difficult.
There was significant latency from keypress to physics impulse.
The physics impulse was calculated including existing momentum, resulting in more flexibility but an unnecessarily steep learning curve.
I addressed these issues in the following ways:
Renamed the grapple to tether jump, this resulted in players not having prior expectations for the ability’s behavior and having an easier time learning the mechanic.
Reduced the cooldown to as low as possible while ensuring that players could not spam the ability to launch themselves an extreme distance.
Reduced the delay from press to cast from .75 seconds to .1 seconds. This allowed it to still match up with the animation reasonably well and made the ability feel much more responsive.
Changed the physics impulse so that prior momentum was cleared before the impulse was applied, which made the result significantly more predictable.
I also ended up using very similar logic to build the boost pads used in several levels by making the impulse strength adjustable and making an adjustable pre-determined vector for the impulse direction. The whirlwind mechanic also uses the same physics logic.
Spirit Path Mechanic
The spirit path is a simple mechanic where running on specific surfaces increases the player avatar’s movement speed. After some trial and error I came to the solution of using a multi-line trace pointing downwards from the player to check for a spirit path physics material on the adjacent surface and increasing the movement speed while that trace detects the appropriate physics material.
Thunder Spear (Cut for Scope)
In the first portion of the second month of the project I created a spear as an alternative to the basic sword the player character starts with. It had the following function:
Standard attack and magic ranged attack
Spear throw
Upon impact it deals damage in a small AOE, and shoots a line trace down from the middle of the spear, if the trace has a positive hit it enables the second activation, if it does not result in a hit, the spear returns to the player.
The second activation causes the player to jump to the spear, playing some special effects and dealing damage in a large AOE.
This feature was cut for four primary reasons:
As we moved towards specialization in our roles on the team, balancing and maintaining the feature would have overloaded my workload.
We changed our level design paradigm from descending to ascending, which made the special ability much less effective.
The ability was fun, but felt significantly overpowered and posed a lot of difficulty when it came to balancing.
When we changed to an ascending level design paradigm we also moved away from fully enclosed spaces, and this resulted in a bug where if the spear never returns to the player, resulting in a soft lock. This bug could have been addressed but because the ability was already on the chopping block because of the other issues it was never fixed.
Thunder Spear Level (Cut)
Along with the thunder spear, I built a level to introduce it. This level was built entirely around teaching the player to use the thunder spear. This level was cut both because the thunder spear was cut as a feature, and because it was built with the old level design paradigm for the game, which was a generally descending path, that was fully enclosed on all sides.
Advanced Movement Level (Cut)
When I created the initial implementation of the grapple, and spirit path I created a level to introduce the mechanics. The level was built in the updated level paradigm which was generally ascending, and an open air “sky island” style. This level was cut as we moved into the polish and bugfixing phases of the project. I needed to focus on a complete UI overhaul, and maintaining the grapple and spirit path mechanics, which put updating the level with final assets and fine-tuning metrics would push me out of scope. Elements from the level did however make it into portions of other levels in the final vertical slice.
Other Miscellaneous Features
Recorded and edited all tutorial videos.
Recorded and produced all voice lines for the boss.
Designed niagara systems and materials for all player abilities (excluding the ultimate ability).
Acted as director and producer for the project, managing vision and scope as well as maintaining workload balance across the team. I also produced all jira logs and had the final say for which tasks were prioritized or shelved.
Designed all 2D assets used across the UI.