top of page
Double Down
A cooperative turn-based RPG where two players must together to defeat a powerful boss.
Developed as a solo project in Spring 2020
Design Reel and Development Information
-
Roles:
-
-
Game Designer
-
Programmer
-
Artist
-
Composer
-
-
Tools: Unity 3D, C#, Adobe Suite, Google Suite
-
Full Development Time: ~3 Months (Mid-January - Late April 2020)
-
Logged Hours: 80+
-
Platform: PC
Intent Statement:
The intent of Double Down is to create a local-multiplayer turn-based RPG in which two players must cooperate to defeat enemies, grow stronger, and eventually slay a powerful boss monster. Gameplay is divided into large global turns, where every existing character - player and enemy alike - takes a single action before moving on to the next character in line. Defeating enemies provides any participating players with experience points, which will allow them to level up, improve their stats, and learn new skills to help them achieve the final goal of destroying the boss. Because of this, Double Down is moderately paced, with each player’s turn being fast enough that players will not grow bored waiting for their chance to act. However, even between turns, players should spend their time speaking and strategizing with one another to improve their chances of victory.
Main Work:
-
Designed and iterated upon various systems, including a turn-based combat system, a level-up system, and a system that allows players to enter each other's battles from a central hub area
-
Designed and balanced two different player characters, a normal enemy, and a boss enemy
-
Programmed the game's various systems to ensure they meshed and worked together
-
Developed various UI elements to help with readability
Design Work:
Systems Development and Iteration
Designing the Combat System
When I began working on Double Down, I knew that I wanted to start by developing the game's turn-based combat system. This is because most of the gameplay takes place during combat, so implementing it immediately would allow me to test and iterate on it more often throughout the development process. I also decided that, in order to best emphasize the game's multiplayer aspects, I needed to ensure that turns did not take too long to complete. This led me to make Double Down's combat fairly standard, with no added wrinkles or gimmicks in the battles themselves. Additionally, I decided to make the turn order not feature any random elements. Instead, it would directly from each character's SPD (speed) stat, with the fastest character moving first and the slowest moving last. This made each turn consistent, allowing players to strategize more easily.
The first iteration of Double Down's combat scene. Note that the player and enemy positions are reversed from their positions in the final game, and that several key features - such as pop-ups for action names, targeting, and abilities - were not yet implemented.
Once I finished setting up an incredibly basic combat system featuring the above mechanics, I then added more mechanics and visual features to help flesh it out. These included a set of five abilities for each character and a targeting system that gave players more control over the battlefield. I also changed the controls to make them keyboard-only, which helped make the game feel like more of a traditional turn-based RPG.
The second iteration of Double Down's combat scene. Note that I readjusted the players' and enemies' positions to make them more readable for a Western audience. I also updated the UI to include pop-ups for action names and made each character's HP and TP bar easier to read.
At this point, I had finished implementing every major part of the core combat system I wanted to have in Double Down. As such, I then turned my attention towards balancing the combat system to help balance out the game's difficulty curve.
Double Down's damage calculation uses a complex exponential formula, where damage is based on a combination of the acting character's ATK (attack) and LV (level) stats; the current action's modifier, if applicable; the target's DEF (defense) stat; a random number between 0.8 and 1.0; and a constant value that acts as a universal multiplier. Adjusting this multiplier has heavy consequences for the formula as a whole, with each "tick" up or down raising or reducing damage by 100% of its base amount. For example, at a "tick" of 1, if a LV 3 character with 10 ATK attacks an enemy with 10 DEF, they will deal about 5.5 damage (adjusted to 5 after truncation). Increasing this to 3, meanwhile, would raise the damage to 16.5 (16 after truncation). This gave me a very easy way to adjust the damage curve to ensure characters would not deal too much or too little damage throughout the game.
Early in development, I had the multiplier set to 5, or about 500% of its base amount. However, I soon found that this number was too high, and player characters gained so much HP that enemies felt completely nonthreatening during the mid-game. To fix this, I reduced the multiplier to 3 - which cut all characters' damage by approximately 40% -, and I significantly decreased all characters' max HP and HP gains throughout the game. This flattened out the damage curve very well and made the mid-game more exciting.
A comparison between the old damage numbers (left) and the "new" damage numbers (right).
As of this point in development, I was satisfied with the current state of the combat system, and I did not want to add any new features or mechanics that could upset its inner workings. As such, when I returned to the combat scene later on, I focused mainly on adjusting its appearance to make it more intricate and visually appealing. To do this, I completely redesigned the scene from the ground-up. I removed the blank platform and dark background, and I replaced them with a scene meant to mimic the hub area's "active volcano" theme. I also added a slight angle to the camera to give the scene more depth. Finally, near the end of the project's development cycle, I implemented animations for each ability. This helped make each in-game action feel more impactful while also giving players a better understanding of each action's effect.
The third iteration of Double Down's combat scene. Note the updates to the scene as a whole, the characters, and the UI. All of these changes helped make the combat scene much more interesting to look at while still allowing me to utilize the core combat systems.
Designing the Level-Up System
When designing Double Down's level-up system, I wanted to encourage replayability and to make players communicate with one another more often. To do this, I designed a system where players can teach their character a new ability whenever they level up. Each character has four learnable abilities: one upgrade to their main skill, one new active ability, and two passives. However, because they can only level up two times per run, players cannot teach their characters every possible ability. Instead, they have to choose abilities that they think will work well, and they are encouraged to make builds that they think will synergize with their partners'.
The current ability screen, which appears whenever a character levels up. The central button represents the character's main ability. The top button teaches their upgraded ability; the bottom teaches their new ability; and the left and right buttons teach their passive abilities. The text at the bottom displays the selected ability's name and effect.
Outside of the ability-learning aspect, the level-up system consists of two other main components. First, player characters earn EXP for defeating every enemy in a battle. The EXP reward is divided evenly among all player characters in a given battle, giving players an incentive to try fighting enemies alone. I displayed this information as a horizontal bar, which fills from left-to-right to indicate how close they are to reaching the next level. When the bar fills completely, the character's level increases. Players can also access this information via a menu in the hub area.
The process of earning EXP. Note that, because Amelie and Hendrik entered the battle at different levels and with different EXP counts, their meters are slightly different.
As I developed this system, I wanted to ensure that the EXP curve felt reasonable, since I did not want players to spend too much time grinding. To accomplish this, I set up the EXP requirements and rewards so players could reach the max level after defeating only three or four groups of enemies. I also placed more enemies in the scene than it takes for both player characters to reach the max level. (There is a total of 540 EXP in the scene; each character needs 150 EXP to reach LV 3.) This proved successful, as players frequently completed Double Down in less than 10 minutes, and several replayed it a few times to test different builds.
The second main component of this system is the level-up effect. Whenever a character's level increases, the game displays a brief animation showing each of their stats rise from top to bottom. This gives players an indicator of how much stronger their characters are growing throughout the game. It also provides a simple, pleasant visual effect where the numbers tick up one-by-one, which I added to make the level-up effect feel even more satisfying.
Amelie leveling up after she earns enough EXP. Note that once a stat stops increasing, the incremented amount appears in yellow. This makes it easier for players to differentiate the increments from the other text and numbers on-screen.
Designing the Flow Between the Hub to Combat
The main aspect that sets Double Down apart from other turn-based RPGs is its focus on multiplayer gameplay and cooperation. As such, to emphasize this part of the game, I decided to create a "hub" area that players could explore during their turns. I also planned to develop the hub so players could choose to either fight enemies or alone or join a preexisting battle. This is because, despite me wanting to make Double Down feel collaborative, I still wanted to give players a sense of independence so they would not always feel chained to their partner. To further this idea, I made enemies give less EXP if players defeat them in groups, making solo combat a viable choice if players want to level up more quickly.
The current iteration of the hub area. When players interact with one of the sparkling blue points, the game prompts them to engage the on-screen enemies in battle. If another character is already at one of these points, players can choose to join them in a preexisting battle.
When I began working on the flow between the hub and combat, I had already finished setting up the core elements of the combat system. I believed this would make the process much easier, given that I would only need to create the hub scene, set up a few persistent GameObjects, and then swap back and forth between the two scenes as necessary. As such, I immediately began setting up the hub area.
While designing the hub, I wanted to make an area that was both visually interesting and fun to explore. The enemies I had developed thus far - a pair of fire-themed birds - inspired me to create a volcano-themed environment. To keep the area from feeling too flat or generic, I set up a raised section near the entrance, and I added several "bridges" that would let players cross over magma rivers. I also placed a number of nooks and crannies throughout the hub, which I would use to hold various enemy encounters.
The original, grayboxed hub. Note that I made the area using a series of Unity cubes, which would allow me to more easily texture them as I progressed through development. I also did not change the layout or enemy placements significantly over the course of the project.
Once I established the hub's layout and allowed players to explore it freely, I then set it up so players could only move during their turns, and that the camera would focus on them during this time. This proved to be very easy, since I had set up the script that managed the game's turn order so it could account for differences between the combat and hub scenes. Creating the actual flow between the two scenes, on the other hand, was far more difficult than I had anticipated.
The core reason for this was twofold. First, the UI object I used to display the turn order did not display the correct information after crossing between the two scenes. Because I made the turn tracker tie lead directly into the turn order script, this often resulted in the game softlocking when the game could not account for an extra combatant or player character. I eventually fixed this issue by cleaning up these two scripts and accounting for some of the edge cases, but this took some time to adjust.
Despite being a persistent object, the turn tracker must add or remove new icons between each scene to accurately reflect the turn order. This originally caused problems when it added or removed too many icons at once, such as when it would copy the acting character's icon without deleting the old one. To fix this, I made the script skip over that character between scenes.
The second issue was a result of the way I carried data between the hub and combat scenes. Several important GameObjects - including the player characters and enemies - routinely switched between the two scenes, allowing me to reference or adjust them as necessary. Less universal objects, however, remained in one scene at a time, and I reloaded and reinitialized them as necessary. This was a problem for the various battle event spaces I placed around the hub, which each held a list of the enemies relevant to their combat instance. Because these spaces did not transfer between the hub and combat instances but the enemies inside them did, they were unable to store the information between scenes, and the list of enemies became full of missing objects. As a result, players could not access any combat instances almost immediately after they started playing the game.
To fix this issue, I made each event space reinitialize whenever the hub scene loaded in. This allowed each event to refill its enemy list between scenes. I originally considered just making the event tiles persistent objects, but I ultimately decided against doing so since they were meant to be part of the hub's environment, and placing them in the combat scene could lead to unforseen consequences.
The code used to set up the events between scenes. The first "for" loop adds enemies to a list depending on whether or not an integer value equals the event's internal number. From there, the game clears the old list and replaces it with the new one. Finally, the game checks if every enemy attached to the event is dead, and if so, it makes the event inactive and invisible.
After I finished making the transition function the way I wanted it to, I set about incorporating additional mechanics and making the flow more visually pleasing. The main mechanic I wanted to implement was death. Before I finished implementing the hub, fallen characters remained dead until the end of the current battle. However, I soon realized that this was not fun, since one player would often be stuck in a fight for a couple minutes while the other had to patiently wait to play again. Dying against the boss was even worse, since it completely removed one player's ability to interact with the game.
To alleviate this problem, I changed the mechanic to account for the new connection between the hub and combat scenes. This meant that after a character died, they were removed from their current battle, and their player had to wait two turns before they could act again. I found this to be a much stronger solution, as it allowed me to punish players for failing while still letting both of them participate as often as possible. It also allowed players to perform more interesting strategies - such as sacrificing themselves for their partner's sake and scouting out harder encounters ahead of time - because the consequences of death were now so much lighter than before.
The updated death mechanic. After two turns, Hendrik will revive with full HP and TP. Note that if Amelie dies during this time, both players will receive a game over.
Finally, I set about making the transition between the two scenes more interesting. One new change included a "wipe" effect, which I used to make the flow between the two scenes feel less jarring and sudden. I also integrated an effect where, whenever a character enters a battle for the first time, they run in from the left side of the screen. I believed this would help add continuity between the hub and the combat scene, and that it would also make every new battle feel more exciting. To further improve the connection between the two scenes, I also composed the hub and battle music so they would naturally flow into one another. This also ensured that players would not have to deal with the music suddenly starting and stopping every few seconds.
Character Development and Iteration
Developing the Player Characters
When I first began working on Double Down, I knew that I wanted to create two distinct player characters with four learnable abilities, apiece. I made this decision for two reasons. First, I believed that it would give players plenty of room to build their characters as they liked without overwhelming them. Second, I realized that if players could only teach their characters two abilities per playthrough, their would only be six possible ability combinations per character. This would make it much easier for me to test and balance the characters throughout development.
I then turned to developing the characters themselves. I immediately knew that I wanted each character to fulfill a distinct niche, with one being a physical attacker and one being a healer. Later, I decided to give each character a secondary role to make them more interesting. From there, the physical attacker also became a tank; and the healer became a magical attacker.
I first set about creating the attacker, who I would later name Hendrik. I set up Hendrik's stats so he had high HP and ATK, medium SPD, and low TP and DEF. This established him as a fairly standard warrior-type character, though his health allowed him to tank, if need be.
Hendrik's initial stat sheet, which depicts his stat growths (left) and original abilities (right). To view a larger version of this image, click here.
For Hendrik's original abilities, I wanted to focus on ones that meshed with both of his roles. His original ability, Heavy Slash, was a simple-but-powerful delayed attack that guaranteed Hendrik would act last during the turn he used it. Its upgrade, Heavy Slash+, turned this downside into an upside by both increasing its power and giving Hendrik a 50% DEF buff until it activated. This also synergized with his other active ability, Provoke, which forced all enemies to target him for two turns. Ordinarily, Hendrik's SPD stat would result in him losing Provoke's effect relatively quickly, which forced players to use it again or allowed enemies to attack the other player character. By combining it with Heavy Slash or Heavy Slash+, however, players could keep the effect up for a longer amount of time. To contrast his active abilities, Hendrik's passives were both fairly simple. Each of them permanently increased either his HP or his ATK by 25%, allowing players an easy way to bolster his two main roles.
The first iteration of Hendrik's "Heavy Slash+" ability. Note that, while it is incredibly powerful, Hendrik is also forced to act last during the turn it activates. In future iterations, I made the turn tracker (bottom) properly display that Hendrik will act first during his next turn.
During an early round of testing, I found some problems with Hendrik's design. While his active abilities functioned as intended, his passive abilities were far too polarizing. HP +25% was surprisingly weak, and very few testers seemed interested in using it. ATK +25%, on the other hand, was absurdly powerful, and it trivialized every encounter excepting the boss. To fix this issue, I decided to completely revamp Hendrik's passive abilities to make ones that were both more balanced and more interesting. This led me to make the following changes:
-
HP +25% became Wall of Blades, which gave Hendrik +1 DEF for every 5 points he had in ATK. This meant that if Hendrik had 20 ATK, he would gain +4 DEF.
-
ATK +25% became Patience, which gave Hendrik a one-turn +25% ATK buff whenever he ended a turn without dealing damage. Unlike the original passive, this ability stacked, and Hendrik could gain up to +50% ATK at a time if he ended two turns in a row without attacking.
These ability changes proved effective. Patience was far less overpowered than ATK +25% due to it taking at least one turn to activate. It also synergized well with Hendrik's kit, acting as a pseudo-upgrade to Heavy Slash, Heavy Slash+, and Provoke. Wall of Blades, meanwhile, was more powerful than HP +25% due to it providing Hendrik with more effective tank stats. Later in development, I further buffed Wall of Blades by reducing the ATK requirement to 4 points, rather than 5. This opened up room for players to build Hendrik as a pure physical attacker, a pure tank, or a hybrid of the two.
Hendrik's "Patience" passive activates automatically if he ends a turn without dealing damage. Players can couple this with his active abilities or the "Defend" command, drastically improving his damage output.
As I was busy working on Hendrik, I was also creating the healer. As development progressed, I eventually decided to call her Amelie. To stand apart from Hendrik, Amelie had high TP; medium HP, ATK, and DEF; and low SPD. This allowed her players to cast plenty of spells that both supported their partners and decimated enemies.
Amelie's initial stat sheet, which depicts her stat growths (left) and original abilities (right). To view a larger version of this image, click here.
For Amelie's original abilities, I wanted there to be significant overlap between her support and offensive abilities, since I imagined that would make her more fun to play. Her innate ability, Blood Draw, was a spell that absorbed HP from a single enemy and then split it among all party members. Its upgrade, Blood Draw+, increased both the ability's base damage and the amount it healed the party for, making it much more potent. Her second active ability, Injection, was a simple buff that increased an ally's ATK by 25% for three turns. This was meant to let her assist Hendrik by increasing his damage. However, it also provided some synergy with Blood Draw and its upgrade, since Amelie could raise her own ATK to increase their damage and healing. As with Hendrik, Amelie's passives each permanently raised one of her stats by 25%. In her case, the two stats were TP (to let her cast more spells) and SPD (to let her act more quickly each turn).
The first iteration of Amelie's "Blood Draw" ability. Note that whatever damage it deals is then split evenly between all party members. This made it less potent when multiple player characters were engaged in a single combat instance, which helped prevent it from becoming overpowered.
During the same round of testing where I discovered problems with Hendrik's design, I also found several issues with Amelie. Blood Draw and its upgrade were far more powerful and enticing than any other ability in her repertoire, to the point where nearly every tester chose it. Injection, meanwhile, saw nearly no use at all. Amelie's passive abilities were also far too weak. TP +25% was fine for the most part, but few testers ran out of TP during the boss fight. SPD +25%, meanwhile, made no impact on the game at all. To fix this issue, I completely redesigned Amelie's second active ability and her passive abilities to make them more usable:
-
Injection became Transfusion, which transferred half of Amelie's current HP and TP to an ally. Amelie could not use this ability if she was the only player character in a given fight.
-
TP +25% became Desperation, which gave Amelie +1 ATK for every 5 TP she consumed in a given battle. This meant that if Amelie had 5 TP out of 20, she would gain +3 ATK until the battle ended.
-
SPD +25% became Refresh, which recovered 15% of Amelie's TP whenever she defended.
These ability changes made Amelie much more interesting. Desperation opened up room for players to create an offensive Amelie, with her ATK rising above Hendrik's after she consumed enough TP. Refresh, meanwhile, allowed Amelie to slowly recover her TP if need be, which I believed would allow players to engage in longer battles than before. Finally, Transfusion allowed Amelie players to perform a riskier-but-more-potent heal that could help a tank-built Hendrik stay alive longer or provide an offensive Hendrik with more TP to use his abilities. It also synergized with both Desperation (as it depleted Amelie's TP far more quickly than Blood Draw or Blood Draw+) and Refresh (as it allowed her to keep recovering TP that she could send over to Hendrik). This opened up room for players to build Amelie as a pure healer, a pure magical attacker, or a hybrid of the two.
Amelie's "Desperation" passive activates automatically as she consumes TP. As I progressed through development, I added a set of particle effects that grew in size every time Desperation increased her ATK. This allowed players to easily understand Amelie's power at a glance.
Late in development, I found that there were still several balancing issues in regard to the player characters. While Hendrik was fine in his then-current state, Amelie's abilities were still far too polarizing. This is because her TP was too high. Blood Draw only took 5 TP to cast, and because Amelie started with 34 TP (and had up to 54 at Level 3), she never ran the risk of running out in any battle. This made Refresh much weaker than I had anticipated. To fix this issue, I nearly halved Amelie's starting TP and TP gains. I then buffed Refresh to restore 25% of her TP, rather than 15%, and I doubled Desperation's ATK bonus to account for her reduced max TP. This proved incredibly effective, as it made it far more difficult for players to repeatedly cast Blood Draw or Blood Draw+ in a single battle. It also made both Refresh and Desperation more powerful, as the former helped keep Amelie from running out of TP, while the latter ramped up twice as quickly and made it easier for players to create an offensive build. Finally, to keep Hendrik's stats consistent with Amelie's, I halved his starting TP, his TP gains, and his abilities' costs. This also made it easier for Amelie to restore his TP with Transfusion, which kept that ability from becoming underpowered.
Hendrik's (top) and Amelie's (bottom) current stat sheets. To view larger versions of these images, click here (Hendrik) and here (Amelie).
Hendrik fighting a group of two Embirds. Note that even when Hendrik is at Level 2 and has the "Wall of Blades" passive, the two Embirds are still very powerful. This helped me keep them enemies threatening even into the midgame.
As development progressed, I did not make any major changes to the Embirds' stats or abilities. Instead, I balanced the player characters around them, which helped make the balancing process much easier.
Once I finished setting up the Embirds, I began to create the boss monster, which I later named the Magpie. Around this time, I decided that I desired two major things for Double Down's boss fight. First, I wanted the boss to feel like a more powerful version of the Embirds, which I believed would help tie the environment together. Second, I wanted the battle to feel dynamic and interesting, with the enemies growing stronger and gaining new abilities as the fight progressed.
This led me to give the Magpie several powerful abilities. The first ability, Feather Storm, was designed as a strict upgrade of the Embird's Beak Stab, hitting three random enemies instead of two. Its second ability, Pyre, was exactly the same as the Embird's. Its third ability was Pyrea - a stronger, group-targeting version of Pyre that it only gained access to when it fell below 50% of its max HP. This skill functioned similarly to Hendrik's Heavy Slash, with the Magpie taking full turn to charge its attack before unleashing it on the party. I designed this ability so players would have a chance to defend before the boss finished casting Pyrea, significantly reducing the damage dealt to their party.
An early screenshot of the boss preparing to cast Pyrea on the party.
To further improve the boss, I wanted to give it a threshold ability that would significantly change the boss fight. This was an ability it would use a single time after it reached or fell below 50% HP. Originally, I wanted to make it so the boss would release a "burning mist," which would deal extra damage to any player characters fighting it at the end of each global turn. This effect would remain in-place for the duration of the battle, creating additional tension. However, I had a difficult time implementing this the way I wanted, so I instead decided to make the Magpie's threshold ability a self-buff that permanently altered its stats for the duration of the battle. Originally, this ability gave the Magpie +2 ATK in exchange for -2 DEF, and the game displayed the text, "The Magpie sacrifices its defense for more power!"
The Magpie using its original threshold ability. Note that early in development, there was no indication beyond the text that the Magpie's stats had changed, which several testers found confusing.
As development on the game progressed, I made several important changes to the Magpie. First, in response to testers claiming that it was too difficult to defeat, I reduced its max HP and ATK. This made the boss much more manageable, and few players were unable to defeat it as long as they utilized their characters' abilities and cooperated. Second, I made several changes to its abilities to make the fight easier to understand:
-
Pyrea's name changed to Inferno Breath, and I increased its damage to make it more threatening. Further into development, I also added a particle effect that appears around the boss' mouth as it prepares to use this ability.
-
The Magpie's 50% threshold ability became "The Magpie beats its wings furiously!" This move swapped out the ATK increase and DEF decrease for a permanent 15% buff to the boss' ATK and SPD. The buff's effect was visible next to the Magpie's health bar.
-
I added a new threshold ability when the boss reached 25% of its max HP: "The Magpie's wingbeats grow faster, still!" This ability increased the Magpie's ATK and SPD by an additional 10%, giving it a total 25% buff to both stats when accounting for its other threshold skill.
These alterations helped make the Magpie feel more powerful and exciting to take down. Its self-buffs were especially dangerous, as if players failed to kill it quickly enough during the final phase of the fight, it could easily tear through even a defensive party. The name changes and the inclusions of buff icons for the boss' threshold abilities also made it much easier for players to understand how said abilities worked, improving the game's transparency. Increasing Inferno Breath's power and telegraphing it more clearly also made it feel more threatening, which encouraged players to guard more often so they could avoid having it kill one or both of their characters.
The current iteration of the Magpie's Inferno Breath ability. As the boss prepares its attack, a "smoke" particle effect appears around its mouth. This helps telegraph that the Magpie is going to cast Inferno Breath on its next turn, making it easier for players to react. Also note the ATK and SPD buff icons to the right of the Magpie's health bar, signalling that it used a threshold ability.
Finally, as I approached the end of development, I decided to create a unique death animation for when players defeat the boss monster. This was meant to add a sense of triumph - and, if the fight proved particularly difficult, catharsis - to the encounter. It also allowed me to make the boss feel truly unique and separate from the normal enemy encounters.
When the Magpie dies, the screen flashes twice, the boss grows in size, and it rapidly shakes back and forth as it fades out.
Programming Work
Coding the Game's Systems
Because Double Down was a solo project, I needed to set up and program each of the above systems myself in order to make them work as I wanted. While developing the game, I often strove to make my code as malleable as possible. This would allow me to return to it and make any necessary changes to it throughout development. For example, while programming the game's turn manager, I initially checked to determine whether players were in the combat scene or the hub, even though I had yet to create the hub at this point in development. This made it very easy for me to slot the hub's information into the code when I put it together several weeks later.
Code from the original "TurnManager" script. The top function goes through the list of combatants and sets up the turn tracker. The middle function resets the turn order if necessary and moves the turn tracker, which then starts the next round. The bottom function checks if characters are or are not in combat. This let me set it up so I could account for the hub later on.
One of the most intricate parts of the codebase involved transitioning between the combat and hub areas. In order to make sure that the characters and enemies both transferred between the two scenes properly, I made them all persistent objects. However, I also needed to transfer other information for these objects between each scene. For example, if a character was set to appear in a combat instance, they needed to be at a specific position on-screen when the battle started. Conversely, whenever the game shifted back to the hub, every character needed to return to their previous position.
To accomplish this, I created a new manager whose purpose was to carry all necessary values between the two scenes. This manager accounted for five possible scenarios: creating a new combat instance; moving players and enemies into a preexisting instance; moving player characters and enemies out of a preexisting instance; destroying an instance when the players characters defeated every enemy; and resetting an instance when the enemies defeated every player character. This allowed me to easily set up every piece of information, which included each character's position, the direction they faced, and any music changes.
Overall, I found that programming Double Down's systems was easier than I had expected. Some areas, such as the main combat loop, did not take long for me to complete at all, and many of them came out very clean and easy for me to adjust. That said, some parts of the game proved incredibly difficult. For example, getting the process of switching between the hub and combat scene to work proved very difficult. I spent roughly a week just getting it to function, with another several days going towards bug-fixes general cleanup work. Regardless, programming this game proved to be an incredibly valuable experience. Outside of a few notable instances that I would like to clean up in the future, I am incredibly happy with Double Down's codebase and with how well the game runs in general.
UI Development
Creating the Game's UI
While I developed Double Down, I wanted to ensure that the game's UI properly conveyed every piece of necessary information without distracting from the gameplay. To help me accomplish this, I first examined several other turn-based RPGs and took note of how they use their UI to guide and inform players. This eventually led me to my main artistic inspiration, Square Enix's Octopath Traveler (2018). Octopath features a very simple, monochrome user interface, which helps keep it from distracting players. As such, I wanted to emulate this style in Double Down, especially because I was also making a 3D game with 2D sprites.
The turn tracker is the most obvious inspiration. As in Octopath, the turn tracker consists of a series of icons that each represent one combatant. Each time a character acts, the tracker moves one space to the left, and the next character in line takes their place. I wanted to use this type of timeline because it allowed me to easily showcase the turn order, which I believed would be beneficial given Double Down's multiplayer focus. It also let me separate combat into a series of global turns, where changes to a character's SPD stat can heavily impact their placement in the turn order. In terms of visuals, I initially toyed around with various shapes for the main icons, but I found that the diamond-shaped ones were sleeker and less distracting.
The original iteration of the turn tracker (top) compared to its current iteration (bottom). As I progressed through development, I updated the icons to contain images of each character in the scene, removed the "inactive" white icons, and added text reading "Next Turn" to the second group of icons to make the UI easier to understand.
Another major part of Double Down's UI is its in-hub menu. This was a menu I designed to help players have a better understanding of their characters' capabilities, which they could open and interact with at any time while exploring the hub. The menu consisted of two pages: one that showed the acting character's stats and one that showed their abilities.
The first iteration of the in-hub menu. The left section contains information on the character's name, portrait, and level. The right section contains either the character's stats or abilities, depending on the page. I decided to make the stats page display information on each stat's boost from passive abilities, making it easier for players to see how they affect their characters.
However, I soon found that this menu was fairly bland and uninteresting, especially as I began to work on integrating art into the game. I also realized that the white text was a bit hard to read against the gray background, especially in certain parts of the environment. This issue was present in some other areas throughout the game, as well, such as the level-up screen. To alleviate this problem, I decided to heavily overhaul the visual design I used for each menu, starting with this one.
The current iteration of the in-hub menu. To make the text easier to read, I swapped out the light gray background for a semitransparent black one that used the same border as the turn tracker's icons. I also replaced the lines between each section with much clearer separations between the panels themselves.
Another issue I noticed involved the way I displayed buffs and debuffs in-game. Originally, I did not include any visual indication that a character had received either a buff or a debuff, which made it very difficult for players to properly utilize or understand them. As development progressed, I added new icons for four types of buffs and debuffs: ATK, DEF, SPD, and Aggro (as in Hendrik's Provoke ability). These icons appeared next to each character's personal data. Each of them contained two extra components, as well. First, they showed a small number to indicate the number of turns left until the effect disappeared. Second, they showed one or two arrows, which helped display an effect's strength.
Hendrik's buff and debuff icons after using his "Heavy Slash+" ability. Buffs are pictured with blue, upward-facing arrows, while debuffs are pictured with red, downward-facing arrows, instead. The number of arrows present on a buff or debuff shows its strength.
Developing the Enemies
To give players something to fight throughout the game, I developed two distinct types of enemies: a "normal" enemy and a powerful boss monster players needed to defeat to win the game. First, I set about creating the regular enemy. I decided it would be fun to make a fire-themed monster, which I soon dubbed the Embird. I also decided to give the Embird a fairly simple set of stats and abilities. To help make it easy to defeat in the early game, I made it so each player character could defeat it in either two-to-three hits even at Level 1. I then gave it two basic abilities. The first ability, Beak Stab, dealt low damage to two random enemies, while the second ability, Pyre, dealt higher damage to a single target. This made Embirds fairly interesting to fight, especially when in groups of two or three.
Code from the "TransitionManager" script. When setting up a new scene, I first remove all player characters from the "playerChars" object, which I use to determine the characters who appear in the turn order. From there, I add the current player character as the object's only child, and I set up the "enemyChars" list for the same purpose. To view a larger version of this image, click here.
bottom of page