Faux Fliers [Unity3D Dev Case Study Ext.] : Designing a Flying Game around the Inability to Fly
Note: This post is the original case study written for the portfolio, and acts as a more in-depth analysis of my process. The current version of the case study is shortened for lighter reading.
As a gamer, flying in a video game is one method of play we don't give much thought to. But whether the game is a shoot-'em-up like Ikaruga or Luftrausers; an otherworldly take like Captain Forever or Lovers in a Dangerous Spacetime; or something closer to a 3D simulation like GTA V's airplane piloting or Kerbal Space Program's rocket builder, flight design has come in many variations that wouldn't have worked in games other than what the flight had originally been designed for.
If you're like me, I'm not all that thrilled when hearing about a flying game. The first thing that comes to mind is usually a flying simulator, which can look tedious and basic at the same time. But after having developed Breaker Breaker, I learned that flying is just a way of reaching an objective. How the plane soars and spins can say a lot about the game-- including the power ups and other systems that help make flying such a breathtaking experience.
While brainstorming the prototype, I thought about how it felt to lose all control of a plane like in the movies, and what the pilot would be doing to regain control. They'd be pressing a ton of buttons and switches, turning a few knobs, and probably hitting the dashboard a few times. But at the last second, they regain control over the plane and keeps passengers safe using a clutch maneuver! The prototype mainly imitated the dashboard-smacking, which added incredible game flow when switching between smooth flying to chaotic repair. But I wanted to take it a step further and implement the entire gimmick, with a playground-esque user interface with actionable feedback-- crank turns, gear shifts, a smokey engine, and the like.
So here's the challenge I sought to tackle: How do I design an unobtrusive user interface when the player has to switch between flying and regaining control seamlessly?
- Objective: Submit a viable prototype to the NYU Game Center Incubator by the April 8th deadline in order to secure three months of development funding.
- Concept: Faux Fliers is a multiplayer party game where you fix your plane as you fly it.
- Project Duration: 3 Months [9 Jan 2018 - 8 Apr 2018, Part-Time]. Development/Modeling 16 Hrs/Week, Project Management/Design 8 Hrs/Week.
- Approach (Chronological Order): Assess Round 1 feedback; make improvements to the market strategy; asset project scope, development costs, and budget management; write up weekly and monthly production status e-mails detailing goals, progress made, and next steps; draft gameplay changes, control schemes, and user interface; model 3D airplane; program airplane flight controls and smooth out playtest bugs; model sample level design assets; implement shader fixes; model dashboard UI assets; code dashboard UI to manipulate airplane flight if certain parts malfunction; hook up dashboard parts to dashboard gauges to assess airplane status while playing; model and implement prototype level design assets; eliminate as many bugs as possible prior to final build; build final version of game prototype; gather promotional material like screenshots and GIFs; record and submit gameplay video; package and submit all Incubator application content.
- Role(s): Game Developer [Solo Dev, All Roles]
- Collaborators: Jessica Hayley [Unity/C# Consultant]
- Tools Used: Unity3D, MS Visual Studio, Maya, Airtable, Google Suite, OBS Studio, Github
- Links: Windows Download [Pass: incubator2018], Github
My primary goal for this project was to submit a viable prototype in time for NYU's Game Center Incubator deadline for Round 2. I started in 9 January 2018 and had a deadline of 8 April 2018, which gave me three months to design the project, model the art assets, program the game mechanics, craft the level design, and sort out miscellaneous details like weekly status reports and development costs.
Faux Fliers (FF) is based on Breaker Breaker (BB), an earlier game jam project made in July 2017. In BB, the winning condition of the game is to survive long enough to reach max altitude. Aside from the obstacles falling from the sky, your engine has a Durability meter that drains as you fly your plane. When Durability reaches zero, the core mechanic kicks in: your engine breaks and are unable to fly until the engine is fixed. To fix the engine, the player smashes the engine by clicking the right mouse button multiple times (as if they're smacking a television dashboard) which refills Durability with each click. Each Durability repair fix also gives a bit of Health, providing an incentive to purposely break the engine if the player finds it convenient to do so. Once Durability is maxed out, the airplane can fly again and the player is free to dodge and shoot as necessary.
The feedback I received from submitting BB for Round 1 confirmed what major changes needed to be made to the project in order for it to be competitive with other applications. To sum everything up, the goals for for Faux Fliers were: increase commercial viability, define scope further, overhaul design and aesthetics, and submit the project by the April 8 deadline. If the project was successful I could continue working on it from June to August with funding aid from the Incubator, and in doing so I'd be able to polish up the prototype enough to present it to potential publishers.
There are a few obvious risks and challenges with this project. Aside from game jam prototypes, I've never finished and shipped a product to completion before. I'd also be working alone for much of the project, and I'd be resuming college studies in Fall 2018 so the time allowed on the project would be limited. To help ease these risks, I practiced Unity enough to get certified prior to the project in order to cement the fundamentals. As for scheduling conflicts, time management is something I'm no stranger to-- I've often had to juggle a couple part-time jobs with my studies and my personal life, and practicing game development via game jams have helped me better manage my time and project scope in a game development setting.
I'm also aware that I can't do everything on the project-- there'll be areas of the project where it'll be obvious that I fall short. I brought on a Unity/C# Consultant to aid me in major roadblocks, had a couple UX mentors who made the nice gesture to make themselves available, and prepared a strong and passionate line-up of game devs with previous experience (a Sound Designer, Environment Artist, Character Designer, Unity Programmer, and Promotional Artist) who were ready to join once funding was provided.
As hinted in the title, Faux Fliers isn't a game about flying. As a player you join the Faux Fliers-- a rag-tag group of fox-like engineers who have a healthy disregard for safety protocol. They find enjoyment in making anything fly, even if it seems ridiculous or impossible, and then they attempt to pilot it in a battle of tomfoolery.
It usually doesn't work out.
The Design Overhaul
Game Session: Faux Fliers is an online/local multiplayer vehicle party game that is played through a series of mini-games. A group of players play five rounds, and each player chooses their personal preference of a favorite mini-game, vehicle, and map for the game session. Before each round, a mini-game, vehicle, and map is randomly chosen based on player preferences-- whatever preferences are generated are the set constraints for that round. Once five rounds have passed and the game session is over, the points accumulated provide EXP points and Scrap (game currency) to purchase new unlocks for vehicle and avatar customization and mini-games.
Victory Condition: The goal of each round is to score the most points out of all competitors, but each mini-game scores differently. In "Tug of War" for example, each player is connected to other players via rope and points are accumulated over time by staying in the safe zone. But in "Sabotage War," the goal is to be the last vehicle in operation, so points are awarded based on placement (1st, 2nd, 3rd, 4th, etc). In the fifth and final round, the mini-game involves all players working together to pilot and maintain the Captain's airship during flight (more on Captains and airships later). These final round mini-games are all-or-nothing: all players either win or lose, so competitors need to put aside past grudges and work together to ensure victory.
Core Gameplay: There are three main elements to the core gameplay loop-- vehicle control, vehicle breakage, and vehicle sabotage.
- Vehicle Control - At the start of each round, the player's vehicle is in peak rustbucket condition, allowing the player to maneuver as needed.
- Vehicle Breakage - With regular use comes wear-and-tear, so vehicle parts are prone to malfunctioning. When a part is broken, the vehicle starts to behave in a way that ignores player input. Using the interactive dashboard UI, the player can see which part is broken and can begin repairs. Once all repairs are made, the vehicle functions as normal.
- Vehicle Sabotage - What's a multiplayer game without other players messing up your groove? Players can hop out of their vehicle anytime to hijack an enemy vehicle, either by aiming to land on it or using a grappling hook to pull themselves toward the enemy vehicle. Once a player has boarded the enemy vehicle, the player is given button commands to pick the vehicle apart. Once an enemy's vehicle part is successfully broken (or if the enemy manages to kick them off), the player is thrown off the vehicle and must regain control of their own vehicle. Of course, by jumping off to sabotage other players, your own vehicle is susceptible to sabotage without a defense!
Vehicles: There are many types of vehicles available, but here I'll list the three core vehicles that are slated for development-- airplanes, sailboats, and ferris wheels.
- Airplanes - The primary method of travel among the skies. Airplanes can soar upwards or downwards, barrel roll, and pull swift maneuvers with little penalty. With little restraint comes maximum opportunity, providing plenty of freedom for sabotage and minimal punishment for part breakage.
- Sailboats - The primary method of travel on the ocean waters. Sailboats can glide left or right in circular arcs, ride waves, or even use waves as a ramp-- allowing the player to relax the sail and catch wind to carry the sailboat mid-air. Sabotage opportunities are minimal, but a moderate and consistent speed allows players to avoid obstacles with ease.
- Ferris Wheels - An unorthodox method of travel in metropolitan areas. Ferris wheels may be slow and heavy, but they can fit between thin opening and can use rocket jets to propel the ferris wheel into the air. While mid-air, ground friction is absent and acceleration can generate some serious torque, which can give the ferris wheel a big push and some insane momentum to speed past the competition. Unlike airplanes, sabotaging errs on the side of the pilot-- but with the right timing, the sabotager can pull off some nifty tricks.
Multiplayer Setup: To get a game session going, a player invites other players to their airship. As soon as a guest player boards the airship, the host player is labeled as the Captain. As the Captain, all unlocks that the player has accrued are shared with other guest players. The shared unlocks don't only include mini-games, vehicles, and maps, but also vehicle and player customization options, emotes, and unlocks that have even been paid using real money. So, when preparing a game session, guest players are free to use the Captain's assets however they like-- guests can even choose a mini-game preference that the Captain has unlocked, or even fly an airplane that's only available in the Captain's hangar bay. Once all guests leave the Captain's hosting session, guest players lose the temporary unlocks and the Captain is reverted to a standard player as usual.
Due to the the game industry's general aversion to flying games, Faux Fliers' market strategy targets accessibility and availability among family-friendly multiplayer games on the Nintendo Switch.
By being one of the first games to ship free-to-play on the Nintendo Switch, we avoid a bulk of the indie and AAA saturation that, as a new-name, we'd have a rough time competing against. The ability to share unlocks for free is also a huge plus, especially if casual or low-resource players view those unlocks as a value proposition that...:
- They would love to have but haven't invested the time necessary to unlock the desired features.
- They aren't sure whether to get the unlock and want to try it out for a bit.
- They cannot afford to purchase the unlock so players are willing to split the cost and purchase different unlocks, so everyone can use everything.
By valuing the player's resources, we can provide a game experience where the systems in place do not prevent players from playing how they want. Like a trip to the playground, there should be minimal financial cost and little should be in the way between you and the act of play.
While the GameBoy palette and pixel art style was distinct enough to be immediately recognizable among other game jam projects, the aesthetic arose from the game jam's time constraints-- a four-color palette limited the art production enough so as to not spend too much detail on it, and pixel art was what I was most familiar with at the time.
From a professional point of view, sticking to 2D art limited my skill set and I had a growing interest with working in 3D. I also hadn't used Maya since 2015, and 2009 before that, so I wanted more familiarity with the pipeline between Maya and Unity3D. In addition, I wanted to use a brighter toon-like palette to mimic the silly gameplay that would unfold.
When it came to how the game functionally presented itself, the biggest sore spot was the UI. During playtest sessions, players had trouble when receiving the necessary visual feedback to know when their engine broke down, or how to even repair said engine. As a flying game, the controls were slippery but just tight enough to give the classic challenge feel-- players knew what objects were obstacles, what object was the plane, and how to not be destroyed. But due to the engine-breaking being more frustrating than it was enjoyable, players would try to cheat by staying as still as possible. So when it came to feedback delivery, vehicle breakage would also need a drastic overhaul (more on this in the Gameplay Implementation section).
To get started on how to tackle the new UI, I worked on some concept sketches to get a feel for what I would need to model and how the game would be controlled.
I sought to mimic an airplane dashboard without the needless complexity-- as someone who isn't a pilot, I have no idea what anything on the dashboard of an airplane means. Hell, I only really look at three gauges in my own car: speed, gas, and the air conditioning. But something that a car dashboard does a good job of doing is that the important features are big and loud (startup, acceleration, and horn), whereas the less important stuff are smaller or even invisible until they're necessary (low gas, turn signal, engine check, etc).
So in theory, the new UI would have three primary gauges: engine durability, left wing durability, and right wing durability. A large engine and crank turn on the left and right side would be interactive if repairs were necessary; and if repairs were necessary, the engine would stop pulsing, emit smoke, and the plane would tilt downward, while the cranks (and plane) would spin uncontrollably. Two smaller gauges would indicate Hull Health and Engine Temperature, and a series of buttons, switches, knobs, and gear shifts would control power-ups, manual engine break, or seat ejection for sabotage.
Due to my limited ability in 3D modeling, I chose to go with a low-poly route with component-based animation that scales in size as necessary. I'm unfamiliar with texturing as well, so I'd need to either shade polygons directly in Maya or use materials/shaders in Unity to give an object the appropriate appearance.
Faux Fliers has a silly toon-ish vibe, so I modeled the airplane into something with rounded edges that can be sculpted into a small, pudgy shape. A concave single-seating area would be used for the player avatar, and the airplane's parts like wings, wheels, and stabilizers are modeled separately so that they can be removed freely in the middle of gameplay (so as to mimic the airplane falling apart mid-game). By modeling them separately, they can also be given separate materials and shaders which provides freedom of color and texture.
As for the colors, I hadn't decided which palette to go with yet but I knew I wanted it to be the center of attention. A bright red would help the airplane pop, with the secondary white color accentuating that effect. With the rest of the level design environment rarely using any red, it was a safe bet go to with these colors.
The dashboard model is intended to be placed directly in front of the camera, as opposed to on the airplane model itself, so the dashboard and its components are modeled separately from the airplane. Other than that, the modeling process is very similar to the airplane.
In order to figure out the spacing between dashboard components (gauges, crank turns, buttons and switches, etc), I often had to zoom out and see how each component sized up against the rest of the current setup. This would include comparing size, spacing, and camera orientation in a landscape or portrait view (the image to the right is an example of viewing the dashboard as if it were on mobile).
When it came to the buttons and switches, they could be moved around or even deleted based on whether the game would even need those assets or not. I would've liked to improve the dashboard modeling by reducing the polygon count (the gauges, engine, and buttons don't need that many), and in the long term it would be useful to make each part its own component that can be added in-game. This way, the dashboard could be customized however the game designer needed the parts to be arranged-- much like a level editor or an equip-style system.
When I first started game development, there were many game dev jokes on Twitter that had to do with shaders. I didn't really understand what a shader was back then, other than it having to do with how a game asset would look (I couldn't have told you the difference between a shader and a material). But from the jokes I read, it seemed like you had to be a goddamn wizard to use shaders, and that shaders were the bane of every game developer.
Now I understand why.
Upon using shaders in a 3D environment, it involved using a coding language known as HLSL (High-Level Shading Language) which isn't even close to how an object-oriented language like C# is written. I was using Unity 2017.3 at the time as well, so using shaders didn't mean using any form of visual scripting like Unity 2018 does. Basically, I dealt with shading bugs that I was stumped on by using the Asset Store for a temporary solution.
The Toony Colors Pro 2 asset pack ended up being a huge lifesaver. Without flat shadows or outlines, it was difficult to determine the depth and distance of an object, which would have rendered the game unplayable (badum-tshh).
Level Design Modeling
After implementing all of the necessary features and models, I had about a week to implement the prototype's level design. Not a lot of time! The quality of the level design suffered as a result, but I'd like to share my strategy for how I approached the oncoming issue.
Since the art in the game was intended to act as a placeholder until a legit 3D Artist joined the team, I needed to execute on the aesthetics just enough to get the message across. I had a difficult time understanding how to texture and skin 3D models in Maya; so if I were to color a model, the entire model would need to be colored and textured the same way. I also didn't have time to dedicate much time to sculpting complex structures like a tree or a building, so the geometry needed to be simple. To generate a first impression that would generate child-like excitement, the level design would also need bright, toy-like colors. As a result, I chose to build a level made up of toy blocks.
By composing the level design of just toy blocks, many parts of the level design could be easily duplicated and re-used. The downside would be that the game would take a hit on performance since Unity would need to render hundreds of objects at a time. To improve performance, the collision areas are either basic boxes or capsules which don't match up perfectly with the original mesh shapes (ex. the Lego-esque blocks), but match up well enough to get the job done.
Looking back, I should have designed a single room with a challenge instead of a long, looping corridor to test airplane physics. By sticking to something simpler, I might've had more time to implement a goal, winning condition, or even a main menu.
Revising the control input from a 2D setting to 3D was the first problem I assessed. By providing input using the mouse cursor's x-position and y-position on the screen, the 2D prototype used those two values to rotate the airplane on a single axis. In a 3D setting, however, I chose to stick with the mouse cursor input for accessibility benefits and used those same two values to rotate the 3D airplane on three axes instead of one.
To better understand the problem, I sketched out some ideas in order to visualize how the airplane would rotate when the mouse cursor's position is received. This way, I know what axis needs to be rotated-- the mouse position's current quadrant on the screen would help determine which axes to manipulate, and the magnitude of distance away from the origin would amplify the airplane's axis rotation.
The airplane's thrust is also designed to accelerate when input is received, and airplane velocity reaches a max value when used in conjunction with air drag.
A major pain point with the prototype was when the airplane engine broke, which causes the player to become unable to control the airplane (ie. the core game mechanic). After observing multiple playtest session, we realized that players had a difficult time noticing when the airplane could no longer be controlled. Without that essential information, the player couldn't repair their airplane and resume flight. As a result, players grew frustrated with the gameplay due to a lack of feedback.
With engine-breaking being the core mechanic that the rest of the game revolves around, this is incredibly problematic. Seeing how players were unable to make an informed decision at the appropriate time, I set two design goals:
- Improve flight choreography to be more noticeable if an airplane part breaks.
- Implement additional airplane parts to maintain mid-flight.
If the engine broke down in the prototype, the airplane ignores player control and freezes its rotation while emitting darker smoke, with some screenshake and explosion SFX thrown in for game feel. While all that felt great, having obstacles fall at fast speeds would force the player's attention to focus on the obstacles and not so much on the airplane itself.
By separating engine breakage into three components (engine, left wing, right wing), the airplane's flight pattern would be drastically altered if a specific part were to suddenly break. As a result, the flight choreography is drastically improved.
- Engine Malfunction
- Flight Pattern: Zero thrust, casual downward nose dive based on gravitational force. Also overrides all other malfunctions until repaired.
- Player Controls: Ignores player input.
- Dashboard Visuals: Engine emits lots of dark smoke.
- Repair By...: Clicking/Tapping on the Engine within the Dashboard to regain Engine Durability.
- Left Wing Malfunction
- Flight Pattern: Barrel roll in a counter-clockwise direction.
- Player Controls: Thrust can still be used, with minor turning ability.
- Dashboard Visuals: Left Turn Crank auto-rotates chaotically in the counter-clockwise direction, and dark smoke is emitted.
- Repair By...: Press and Hold the Left Turn Crank to halt auto-rotation, then manually rotate in the clockwise direction to regain Left Wing Durability.
- Right Wing Malfunction
- Flight Pattern: Barrel roll in a clockwise direction.
- Player Controls: Thrust can still be used, with minor turning ability.
- Dashboard Visuals: Right Turn Crank auto-rotates chaotically in the clockwise direction, and dark smoke is emitted.
- Repair By...: Press and Hold the Right Turn Crank to halt auto-rotation, then manually rotate in the counter-clockwise direction to regain Right Wing Durability.
- Left Wing & Right Wing Malfunction
- Flight Pattern: Flight rotation is frozen.
- Player Controls: Thrust can still be used, with no turning ability.
- Dashboard Visuals: Same as Left/Right Wing Malfunction.
- Repair By...: Same as Left/Right Wing Malfunction. Once one Turn Crank is fixed, the malfunction effects of the unfixed Turn Crank (like barrel-rolling) start to take effect.
There were a few major roadblocks that occurred during the game's development: (1) airplane flight, (2) collision physics, and (3) dashboard interaction.
Quaternions in Unity are a pain in the ass to work with. It's a lot of trig which is all well and good, but ensuring that the math is cohesive and acts predictably took plenty of trial and error-- a month's worth, to be exact. (Adding up the dev-hours, it's about 2 workweeks which isn't so bad in hindsight.)
The flight scripts close, but I didn't really know for sure until thrust was added-- which needed more trial and error. But soon enough, I got it right! But after a month or so, when level design started to become more essential, collisions were added. Which introduced more bugs.
I spent a couple weeks stressing about the bug, and even after a refactoring sweep and code fixes the collision issues would remain. Out of curiosity I decided to toggle the "Freeze Rotation" option on the airplane's Rigidbody component. That one option fixed the insane collision bounce.
Some things are just that simple.
Implementing the dashboard was a more engaging challenge that I had a better grasp on, but a few aspects of the dashboard needed some kind of circumventing.
Unity's UI system doesn't provide a component where I could rotate the Crank Turns ad infinitum, so that aspect needed to be hard-coded in the game environment. Similar to how flight control was implemented, a custom origin point is set on the screen (which acts as the origin/turning point on the Crank Turn) and rotates the Crank Turn based on mouse position around the origin point. A distance limit is also set so that if the mouse position is too far away from the Crank Turn, the player is unable to turn the crank. Since the screen ratio isn't a perfect square and is almost always rectangular, however, the Crank Turn's area of interaction was an oval instead of a circle. To rectify this, I needed to manually adjust the x-value ratio to line up closely with the y-value ratio in order to create a circular area of interaction.
The Engine, on the other hand, can make use of Unity's UI system. Since the Engine could be repaired by clicking on it multiple times, it functioned exactly like a button would. After adding the proper screen-scaling to the button and overlapping it with the Engine's 3D model, Engine repair worked well! (I didn't have time to spruce up Engine repair effects, so there isn't much smoke or animation appearing on the dashboard.)
I needed to ensure that the dashboard would not conflict with the airplane flight controls, even if the dashboard took up a third of the screen space. To that end, the dashboard is only interactive if an airplane part is in need of repair. Otherwise, ignore the dashboard and fly the airplane freely-- even if you want to fly downward by moving the mouse cursor to the dashboard region. I implemented this by writing an OnMouseOver script that was added to the dashboard game object, so if any part was broken and the mouse cursor hovered over any aspect of the dashboard and used the left mouse button, the mouse command would not affect airplane flight. Implementing the feature this way would help focus the player's attention away from flight and towards the dashboard instead.
Faux Fliers ended up being a great challenge to take on! The project gave me more confidence in my ability as a developer and designer, and if time allows I'd like to work on it again somewhere down the line. I have a hard time calling Faux Fliers' current iteration a working "game" since the win/lose conditions aren't in place yet, and TBH I still want to experience what it's like to drive a ferris wheel haha. Even if the project didn't make it past Round 2, the project can still go so much further.
In the meantime I'll be focusing more on UX research, design, and implementation a la Joybloc, as opposed to taking on multiple disciplines at once. Faux Fliers isn't too dependent on Unity's UI system, so if possible I'd like to work on something that utilizes that a bit more. Working on FF also helped me better understand where the engine's UI system falls short (ex. rotating around a point ad infinitum), which provides a challenge as to how I can improve or augment the Unity UI system.
Thanks for reading!