
Firefall
Firefall was a free-to-play massively multiplayer online shooter, set in a world under siege by the Melding – an energy storm that destroys or corrupts everything it touches. Players suit up in a class-based Battleframe to defend the last remnants of humanity, push back the melding and unlock the Earth. Firefall features deep crafting and character progression mechanics, as well as a host of dynamic content to keep players on their toes.
Much of my work on the game revolved around defining new types of content that strengthened the core vision of the game. I also did some light system work, such as designing our campaign progression system. Much of my time was spent coding in Lua, our primary tool for content implementation.
ARES Missions: Replayable Dynamic Content
These missions take place in non-instanced mini-dungeons throughout the world, and take into account both their type of environment and the faction of the enemy NPCs occupying it to determine what challenges a player encounters. To keep things interesting, the difficulty level, enemy placement, and the placement and number of objectives can all change between each mission. We’ve also added mutators as an additional dynamic element, which can surprise players with a rare miniboss or environmental hazard. With the support of a technical designer, I designed the majority of ARES missions, which served as the core content of Firefall.
How an ARES Mission Spawns
The actual Lua code of ARES Missions has no intrinsic, hard-coded knowledge of any of the mini-dungeons they might occupy. Rather, a parent encounter feeds it a variety of designer-annotated XML data such as the zone it’s placed in, the type of space it is (a cave vs a military base), placement of trigger volumes and so on.
The ARES Mission encounter then interprets this data and uses the constraints to cook up an appropriate encounter for players to encounter here. This process starts from a high level and works downward. Examples of questions the encounter code asks the XML data tables include:
– What is the zone ID? We don’t want difficult encounters in newbie zones, or easy encounters in end-game zones.
– What type of dungeon space is this? We use this to constrain what variant of mission should spawn, based upon what the enemy race’s intentions would be. If it’s a cave, for example, the Chosen probably wouldn’t bother to plant a bomb in it, so the “Defuse” mission wouldn’t spawn here. They may use it as a hidden staging area, however.
Other critical data the encounter looks at is the placement of trigger volumes and anchor positions in the space. While our geometry is not procedurally generated, our enemy and objectives are dynamically placed.
A recursive Spacegraph algorithm executes at runtime to provide the encounter with depth information about each room in the mission space. Some missions care more/less about depth space than others. In a “Data Freeze” mission, for example, players need to interact with a number of hacked terminals. No one terminal is more important than another, so no bias is necessary in their placement.
In the “Defuse” mission, however, there is a primary objective in the form of a Chosen energy bomb. This is always placed in the deepest room available. If there are multiple rooms that share the maximum depth value for that mission space, one is selected at random. Then, supporting objectives – the keys players must use to defuse the bomb – are scattered throughout the rest of the dungeon.
Reimagined New User Experience: First Hour
In the interest of maximizing player retention, the new user experience must be as fun, polished, and breezy as possible. This arguably goes double for free to play, where new players haven’t invested anything beyond the few minutes it took to download and install. I worked with a team of designers to determine what experiences and lessons are crucial to easing a player into Firefall, while implementing tutorial content that incorporated these with minimal user frustration.
Story Campaign Progression System
As a vehicle to deliver highly polished story content, I pitched and then co-designed Firefall’s concept of a campaign progression system. Players earn Campaign Points simply by taking part in any open world activity in the game. Upon reaching certain numerical thresholds, new missions and rewards become accessible. And, because we put so much love into our story missions, we wanted to ensure players felt encouraged to experience them again and again. I factored this desire for replayability into the first UI design, which I then passed off to a UI artist who produced the final concept.
5-Player Co-op Campaign Mission: “Power Grab”
I designed and implemented a cooperative campaign instance for 1-5 players, which averages 30 minutes in length. It features several Firefall ‘firsts’ both in terms of tech and content design, including dynamically scaling difficulty and a few special wow moments I worked closely with AI and vehicle programmers to achieve.
Replayability through Powerful Player Agency
A major goal for Power Grab was to make repeat playthroughs rewarding for players. While the first half of the mission was mostly linear, players eventually arrive at an “abandoned” base with a hell of a problem. A large contingent of enemy forces is arriving in 5 minutes to take it back. There are a few different ways players can prepare the base’s defenses. They can fight their way through the old power station and get the generators back online, powering up ground defense turrets which will fire on approaching enemies. Or, they can work to deactivate an enemy AA gun, allowing the players’ dropship to make automated bombing runs. Gutsy players can even risk it all by splitting their group between the objectives, and hope both subgroups can accomplish their goals before time is up. It’s a more difficult road, but the payoff is great.
“Death from Above!” Delivering NPC Reinforcements as Dropship Paratroopers
Throughout most of Firefall, friendly NPCs and enemy combatants both spawned into the world by suddenly coming into being. In order to secure a more dramatic entrance for our campaign NPCs, I worked with a vehicle programmer to give AI the capability to attach to (and later detach from) seat points within a dropship. This was half the battle; upon detaching, the NPCs still floated through the air without a care in the world, so I set them up to use the player ability “Crater.” Upon ejecting, they used their rocket boots to pull a flip and then scream into the ground boots first, causing AOE damage on impact.
NPC Comrade System
Previous to this mission, friendly NPCs in Firefall had been “spawn and forget.” They could be told where to go, but once they were killed, they were gone forever. I wanted to represent our story NPCs in-mission, and in a way that felt more like teaming up with other humans. For the first time in Firefall, I set up friendly combatants that would enter a “downed” state instead of being killed outright, similar to a player. Downed NPCs would then create a UI rescue waypoint over their heads, and fire dialog calling players for aid. I also wrote navigation logic so that the friendly combatants would follow the player group went and help in combat. This was an interesting challenge to solve, because who should the combatants be following in a 5-player instance? In the end, I set up a series of trigger volumes to measure player density in any given area of the level, and instructed the NPCs to go wherever player density was highest. Then, they chose a random person within that area to follow as the “leader.” I also spent time tuning the relative strength of the NPCs so that they couldn’t win battles on their own, but still felt powerful enough that players were glad to have them around.
Large-Scale Open World PvE Battle: “Orbital Comm Tower”
The centerpiece of Firefall’s Sertao desert zone is the Orbital Comm Tower (OCT), a strategically valuable structure which provides all players in that zone with gameplay buffs as long as it is active. Every half hour, enemy Chosen battleships spearhead an invasion attempt to destroy it. It’s up to players to repel the Chosen and align the OCT’s satellite targeting dishes. Player success culminates in an orbital laser strike that destroys the enemy ships. Failure results in a loss of the beneficial buffs while the OCT’s custodians repair the damage.
This is an open world, multi-phase battle featuring dynamically scaling difficulty, which supports anything from a small squad of players all the way up to 100 players (the zone max). The encounter code accurately tracks players across 4 POIs in a square kilometer as they wander through the battle zone.
Phase 1: Mini-Boss Battle at the base of the Tower
Players are first tasked with defeating an AI Chosen Commander at the base of the tower. The Commander is powerful and is backed up by a large retinue of allied combatants, so at least 8 players are generally required to take him out. This phase acts as a pressure release valve, ensuring that there are enough powerful players present to succeed in Phase 2.
Phase 2: Aligning the 3 Satellite Dishes
After liberating the Tower, players still need to deal with the Chosen Battleships overhead, and for that, they need a little help from orbiting weapon satellites. Players must travel to three individual satellite array stations
Dynamic Scaling Difficulty for up to 100 Players
Firefall’s zones support up to 100 concurrent players per instance, and all or none of those players may choose to engage with the event. Providing a fun experience for a wide variety of player counts was essential, but there were a few main challenges here:
As this event occurs in the open world, players are free to engage (and leave) at will. The difficulty needed to shift dynamically to meet demand.
After the boss battle in the first phase, players split up to align satellite dishes at 3 locations, each being a few hundred meters apart from each other. One location could have 15 players while another could have 4, so the difficulty also needed to scale per-POI.
The solution I came up with was to create and maintain a dynamic array of player participants, both globally and per satellite location. I supplied Player IDs to the arrays through a combination of trigger volumes (is the player physically nearby?) and kill incident listeners (has the player helped kill an enemy AI at this location?). Each player entry also included a timestamp of their last action, which continually decayed if players did not take further actions. If someone arrived, killed a monster, and went AFK, they would stop contributing to the event’s difficulty after 8 seconds or so. The moment our AFK player came back and started killing things again, they would be re-admitted into the array.
Using multiple data sources also allowed me to do things like check against players who might be bunkered up inside the trigger volume at one satellite location but using sniper rifles to shoot monsters at another location, because we don’t want to count that player twice. I was able to measure which location that player was having the most impact at, and keep the player registered there.
A Bias Towards Heart-Pounding Conclusions
When a player begins syncing up a satellite location, the satellite begins progressing from 0 to 100%. The goal for players is to ensure that all three satellite dishes (and particularly the one they’re defending) reach 100% before the global event timer expires and the OCT takes critical damage.
So, why obfuscate player progression behind a percentage? It normally takes 3 minutes to take a satellite dish to 100%. However, imagine a scenario where 2 of the 3 satellites are synced up, but the 3rd hasn’t started yet, and players have 2:59 remaining on the clock. You’d just give up! Showing percentage progress instead of time allows us to move the goal posts for players without revealing the magic behind the curtain.
The really interesting part here is how we play with the goal posts. In situations where players need more time, we could always move the goalposts to (global_event_time_remaining – 1), so that players succeed and blow up the battleships with 1 second remaining, but that’s a little too on the nose. There are limits to our goalpost generosity, of course, but in instances where players are on the edge between failure and victory, a much more powerful equation is (global_event_time_remaining – (random_#_between_2_and_7)). This way, players get a less predictable, more intense, Hollywood-style finish as the clock ticks down. “Will we get to 100% before the timer goes to zero?” The most compelling answer a game designer can supply is, “Yes, but just barely, and only because you’re so great!” as sky lasers come down and destroy the enemy’s ships.