- Platforms: iOS, Android, Fire OS
- Genre: Arcade simulation
- Development Team Roles: Gameplay Programmer and Designer, 3D Modeler, UI/UX Designer, Game Producer, Lead Game Developer
- Engine: Unity & C#
- Version Control: Git
- Studio: Game Pickle
- Apple Store Link: Airplane Flight Simulator
- Google Play Link: Airplane Flight Simulator
- Amazon Link: Airplane Flight Simulator
- Gameplay Videos at the End of the Page or Click to Watch on YouTube
Elevator pitch: Airplane Flight Simulator is an engaging, open-world arcade flying experience, available across iOS, Android, and Fire OS. Step into the cockpit of 15 diverse aircraft, from nimble prop planes to towering commercial jets. Traverse a 100-square-kilometer landscape, featuring 9 airports on 3 islands, each with its own biomes and design elements.
Summary of Core Gameplay: The player assumes control of a character who can interact with airplanes and pilot them from one airport to another. Airplane controls include thrust, steering, brakes, lights, doors, and seatbelts. The game comprises 20 missions, along with side missions and collectibles scattered throughout the open world. Players can purchase airplanes using either in-game currency or stars, earned by completing missions and exploring the world.
My Roles and Responsibilities:
Level Designer: In the first stage of the development, I served as level designer responsible for creating the whole world including designing the terrain, adding props and vegetation, cities and airports.
Gameplay Developer: In the second stage I coded the complete gaming experience, starting from character control, airplane physics, water airplanes, aircraft selection system, coding and designing missions and side mission, implementing menus and advertisements and in app purchases, optimizing the codes for performance, optimizing the world and assets and finalizing the game.
Level Design
The original idea of the game was to create three islands with ocean separating them from each other. Each Island had a predefined structure of where the cities and airport are approximately located as well as the layering of terrains. Link to level design document
During the level design process, Gaia was used, a procedural terrain creator for Unity, to stamp the terrains and scatter small props and vegetation across the terrain based on rules including height range, slope of terrain, layer texture and noises. The same rules were used while texturing the terrain. Using multiple layers to blend textures based on height and noise rules as well as prop placement I was able to mitigate the obvious tiling effect on the terrains. To make the environment more engageable and memorable, a shift in the biome of the third island was made to make it look more distinct, unique landmarks were scattered thoughtfully in the design to improve the navigational cues for the player.
Island 1
Island 1 has one main airport near a city, there is also a deck near water which gives access to select seaplanes. Road network connects airport to city and goes all the way around the island to the deck area, a small village and lighthouse.
Island 2
Island 2 is considerably larger than island 1, having a three-lane complex airport near a big city. There are two mountain ranges with one of them having a short dirt airfield on it and the other one having a military campsite. The road network almost covers all the landmass with buildings on the curbside.
Island 3
Island 3 Is the largest of the three, featuring one main airport and city on a mountain, a military airport and aircraft courier, and industrial area, a unique dirt airfield on an island, A near water airport with a small town, a V shaped countryside airport and an inclined airfield on a snowy mountain.
Game Development & Programming
Aircraft Physics: I started the programming of the game with aircraft physics. The mechanics of the airplane was separated from when flying and while on the ground, for the ground physics unity’s built-in wheel collider was used with heavy modifications to make it stable while steering the airplane in fast speeds. An airplane would only enter flying state if it had enough speed to compensate for enough lift force to fly. The flying mechanics was handled manually to simulate arcade mechanics. All the inputs calculated would override the velocity and angular velocity of the airplane. Player controls the airplanes using a thrust slider, a steering/yoking pad and a brake button.
Character & Inputs: Character controller uses the default controller from unity. Character has the ability to enter and exit out of airplanes. For the input system, unity’s new input system was used to map inputs to actions. Controllable game-objects derived from an interface that had two functions for connecting and disconnecting from the input. the PlayerInput and AircraftInput class derived from IControllable, were responsible for connecting the CharacterMovement class and AircraftPhysics class to the input system in the overridden functions. There is a singleton class which holds the current IControllable instance, if a new instance wants to connect to the input system the previous one will be disconnected in the setter of the variable. This system ensured only one object received input during the gameplay and the transition between character and airplanes is without hinderance.
Missions: Missions are created using an event-based approach. A mother class called Mission was created and handled all the stuff related to get a mission loading, placing the player at the correct position, spawning the correct airplane, finishing and clearing the mission. Then for each individual mission a child class was made to add mission logic, ex. showing tutorial prompts, receiving trigger events, checking the star rating for the mission, changing airplane aerodynamics based on weather, adding timers, etc. Most of the functions on the mission class were bind to a trigger box inside the level. For example, each checkpoint fired events to enable the checkpoint and communicate with the mission in case especial actions were required. All of the data for each mission like name, task for each start, dialogs, etc, were stored in a scriptable object. Before the missions were implemented, a separate document was created to write the story and gameplay of each mission, although they changed a bit during actual development. Link to mission design document
Level management: Elements of the game were placed in different scenes with all except the Menu Scene unloaded at launch. Then Environment (which only contains terrains and static objects) scene was immediately queued for async loading when player started the game. after the loading, runways, buildings and props, which each of them was in a separate asset bundle was loaded and instantiated into the world. Asset bundles ensured the game did not try to load a very large level all at once which would cause the game to freeze and crash eventually. Each mission had its own scene, making it easy to add them to the game and once unloaded they would clear up all connections with the flow of the game.
Level of Details: For populating the terrain and covering the empty areas a handful of trees had to be placed in the map. This challenged the LOD system since the default unity’s LOD system is not efficient on mobile phones. To solve this problem and switch between tree mesh and billboard a custom LOD system was needed. In this system, trees were broken down into chunks. Each chunk was a circle with a center and radius. All of the trees that fitted inside the radius of this circle were grouped together, then instead of checking the distance of all the trees in the map from the camera, the distance from center of the circles were checked, and if that circle was close enough to the camera, then the trees associated with it would update their billboard and mesh. If a circle would get too far from the camera all the trees would get disabled and not updated anymore. For better performance, even the active circles did not update all the trees in one frame, but rather they were spread along multiple frames to ensure there is no FPS drop while activating and deactivating objects.
Lighting and game feel: The game features real-time day-night cycle with 24 minutes in real life equal to 24 hours in game. The system used multiple sky materials for each time of day, as well as different fog color and ambient color. The sun and moon also changed their position in sky and they would get bigger or smaller based on their position. The script for blending all these parameters for creating a seamless had to be optimized to run only one in a second, and to also break down the task into multiple frames. Fog was added to limit the distance player could see; this would give the player a tendency to explore the world by flying to each location. It also gives the illusion that world is bigger than what they think. To blend the fog with horizon, a hollow cylinder with inverted normals follows the camera, this makes sure the fog is applied up to the horizon and world would not like its floating on the air. Two layers of clouds were added at different heights to transfer the feeling of increasing altitude to player. During the day birds sound plays in jungles and at night there is owl sound. With the addition of wind and ocean sound the experience became more immersive. Also, there are NPC ships, boats and airplanes.
Performance Analysis & Optimization: By far, the most challenging part of the development process was optimizing the game. Given the game takes place in an open world with a huge asset database, textures had to be optimized to the highest level possible which would not sacrifice visuals too much. ASTC and ETC Crunched formats were used for textures. Due to the project targeting very low end and old operation systems the use of ASTC compression was limited (old devices don’t support ASTC) to only transparent textures and a few textures which would not benefit much from ETC. All UI textures were packed together using Unity’s sprite packer tool to reduce size as well as reducing draw calls. Using a plugin called mesh baker, I combined a lot of material and textures together, resulting not only in draw calls improvement, but also reducing game size and memory usage. Some models had to be simplified by our 3D modeler to be suitable for Unity’s dynamic batching. Models that did not reach the triangle threshold for dynamic batching were set to be statically batched. This included city areas in both island 1 & 2. This increased game file size which put more stress on reducing the size of the assets. All materials were assigned a unique render que to assure there were no collision in batching process. For audio, all crips were formatted using Vorbis compression and quality set to the lowest possible. Since the musics were the largest clips, they were reduced to 22050hz sample rate. Based on the usage of the clips, musics were set to stream from disk to reduce memory usage. More frequent clips used either compressed in memory or decompress on load to fasten the process. Unity’s memory profiler and editor cashe were the main tools used for asset optimization. Memory profiler also helped in optimizing the scenes by showing the memory usage of empty game-objects. All the empty game-objects were removed and mesh renderer was moved to the root object which helped to greatly reduce the number of objects. Unused cube-maps were found and removed from scene lighting setting.
Unity’s profiler helped in the optimization of scripts. Update functions and frame by frame callings were removed wherever possible. Instead of using public getters each frame, they were cashed in the start function. All literal strings were converted to const variables to greatly reduce garbage produced from code.
Project Finalization: After the core mechanic of the game was finished, a lot of adjustments had to be made to improve user experience by adding little details like guides for operating the airplane, teleporting player to the next av available mission, improving the design of missions, etc. Trello was the main project management software used for this game. Below are some of the tasks defined in the Trello board.