Lead Programmer - 14 Developers - 6 Months Development Time -
24 Hour Weekly Work Time - Unrealscript/UDK
Description: Reign of Blades is a fast paced, hack-n-slash game where the player assumes the role of a princess on a quest to restore order to her land. The player must battle through the floating castle of the Gilded Empress and ultimately face her. Using the game's helmet swap system, the player can take on various abilities and weapons to help overcome combat encounters.
Team Composition:
1 Game Designer
1 Producer
2 Programmers
6 Level Designers
4 Artists
Roles and Responsibilities
Since our team had two programmers, I took on a very generalist role and touched about every aspect of programming for the game. As our team composition included six level designers, my goal was to make the systems of our game as data driven as possible and rely heavily on UDK archetypes. We took a very iterative approach to our systems with the goal of getting them out to designers as early as possible in the production process for designer feedback. My main responsibilities were to create a flexible encounter system for designers, the player helmet swapping mechanic, actor AI and boss AI, player controls, and integrating all the game systems together.
Primary Responsibilities
Implemented player controls and combat targeting system
Implemented blink dodge mechanic and associated landing algorithm
Designed and implemented an archetype driven, flexible wave encounter system with multiple end conditions and kismet exposure.
Scripted and exposed all enemy AI and boss AI for designers
Scripted and exposed the Turret trap, FooDog trap, and Destructible Spawners
Scripted destructible barrels and configured rigid body simulation
Exposed life cycle events and handles for core gameplay systems, enabling designers enhance gameplay feel by adding effects such as camera shake to super attacks
Implemented helmet swap mechanic and pick up system along with interpolation effects
Implemented the localization pipeline and localization utility functions
Provided back-end support for HUD and Game Menu's
General bug crushing for all game systems
Player Controls and Combat System
Since our game was based around fast paced combat, we needed our controls to be as responsive as possible. Some of my initial effort was spent implementing a smooth range of movement for the analog stick. This allowed the player to use finesse when moving to plan their next attack or dodge incoming projectiles.
Since dodging and avoiding attacks was essential in our game, much development effort was put into being able to cancel attacks or switch at a moments notice. One of my core responsibilities was over-seeing this and responding to play-tester feedback to improve the responsiveness. If a player were in the middle of winding up a ranged attack and a projectile was about to hit them, we wanted the player to be always be able to react and dodge by cancelling the attack/animation and engaging in another action.
One of the systems that originated as a result of play-tester feedback was our auto targeting system. In early to mid development, players were expressing issue with the amount of multi-tasking required to be successful in our game. Many players felt it was too difficult to maintain orientation towards enemies while attacking and also be focused on dodging incoming attacks. We wanted our game to appeal to more than hardcore players, so I implemented a targeting system that helps orient the player to their foes based on the orientation of the analog stick. This allowed players to focus less on their positioning and orientation and focus more on dodging and their changing surroundings.
The algorithm is simple, yet effective. It first collects all targetable enemies within the player's weapon attack range. Next, it calculates the forward facing vector of the player and takes the dot product of the normalized difference vector of the enemy to the player. The largest value of the dot product prevails and that enemy becomes the current target. This proved to be very efficient and not hinder performance frame to frame.
We also did not want players to walk up, mash X, and win the game. I implemented a designer exposed threshold for dot product result to cross in order for auto targeting to be used. This way the player would have to think about who to target and be strategic in the selection.
Encounter System
One of our development goals was a robust wave encounter system, which empowered designers to create a diverse set of unique combat experiences. This was a large focus of my development efforts.
Each combat encounter consists of one or many combat waves. Only one wave can be active at a time and has a unique end condition(s) set by designers. Designers can control if a wave ends due to a time limit, a trap structure being destroyed, or certain enemies defeated. Each wave and encounter also has exposed life cycle events each with provided hooks to kismet. This allowed designers to create interesting cinematic events before and after waves or trigger environmental effects to occur. Combat waves consisted of wave groups, which were data structures containing groups of enemies and or structures with their associated spawn or entry mechanisms. The combat encounters could also be reset on player death or due to game events.
The picture below is an example of our Whack a Mole encounter created by one of our designers using the combat encounter system.
Game Post Mortem
What Went Well
- The plan to utilize a data-driven, archetype heavy approach to UDK development paid off. It fit well for our team composition and empowered the designers to create many interesting combat styles for the player and also a variety of unique enemies. Although it did have some downsides (explained in what was learned), the benefits were worth it.
- We picked our battles wisely. At the very start of the project, we lost a programmer on our team, which left us with two, including myself. Because of this, we engaged in careful planning very early on, deciding which systems to prioritize first in order to best benefit our team composition. We focused on systems involving our combat system and the core mechanics revolving around it. This let us push out the combat systems early in order to get feedback. This let us iterate on core combat systems early and often, which led to a polished final product.
- We responded well to user and play-tester feedback. Many of our best improvements to our combat system came from play-tester and user feedback. We were able to incorporate suggestions into our systems at a face pace and bring them out for testing.
What Went Wrong
- As lead programmer, I made the decision to build our game from the lowest possible level of UDK's Unrealscript class hierarchy. While this gave us complete ownership over our code, it brought up many unforeseen issues which cost us development time. For example, UDK's pathfinding system would often break down when using lower level scout classes that did not extend from the UT or UDK base. This meant we had to spend ample time finding workarounds for pathfinding solutions for larger enemies and bosses. I had to implement custom pathfinding nodes and recovery nodes to assist enemy's in executing their paths who did not fit in with the built in scout file's descriptors. Another example was the inventory system causing crashes in native functions early in the project. Certain UDK native functions (we did not have access to native code) made assumptions about inventory extending from base UDK and above. This meant we couldn't take advantage of certain native functionality and had to write our own inventory system and integrate it with UDK pathfinding. Both of these issues combined cost us around two weeks of development time that we had not anticipated.
- We overworked ourselves during production. While it was admirable to not scope down when we were down to two programmers, it was a mistake in retrospect. While we did pick our battles well, there is often no substitute for having more good people on the team. We should have revisited scope much earlier on.
- While this was not my first time being programming lead or a team lead, it was my first time doing it with a larger development team. I did not do a good job filtering suggestions and helping to manage my other programming teammate's workflow. We would often find ourselves getting pulled in ten different directions and unable to find a reasonable gap of time to focus on a particular task. This led to diminished productivity at times and often more stress. I am a people pleaser at heart, and need to work on implementing formal communication pipelines so that my team can work more effectively.
What Was Learned
- While data-driven, archetype focused development in UDK greatly empowered the designers, it is worth mentioning it does come with a price. Towards the end of the project, we shipped with using around 100 archetypes for our actors, entities, and items. Because of the sheer amount of archetypes and their possible permutations, this created quite the debugging challenge. Debugging effort duration were often increased as it took time to reproduce archetype setups and the exact scenarios they were used in. This made me really appreciate the value of dedicating development time to testing systems. In future game projects, I will anticipate this better by allocating more development time for debugging.
- Building a combat game is very difficult! Some of the most time consuming and difficult problems were getting combat to feel responsive and impactful. We iterated on our combat collision system about five times before we felt satisfied. For example, we wanted particles to appear exactly where the weapon connected and the camera to shake when the impact felt appropriate. If I were to work on a combat game again, I cannot stress how important it is to be iterative very early on and respond to player feedback.