Monday, April 30, 2018

Loadout screenshots

The "loadout" is underway, which contains the higher level features to purchase and upgrade equipment, skills, open reward chests, etc. I wanted to have multiple currencies in addition to the usual coins. Well, shiny gems were not a wise option, because those are abundantly matched for temporary resources to activate skills. Instead I chose cherries, peaches, and radishes to barter with the bunny merchants. The food can be grown and harvested over multiple play sessions, which makes more sense than random chests and coins in this freemium game. Bunnies favor food over gemstones, so it's a twist on the value of objects in this fictional universe akin to Defend Your Nuts and Demons Down Under.

Once this is complete, then I am that much closer to a beta release on Google Play.

Weapons Loadout

Skills Loadout.

The weapons are used automatically when gems of the hero's color are matched. Skills are used by placing its respective pattern on the battle board. The three red dots connected by lines in the skills loadout depict that all three enemies are targeted by toxic rain. If there is no connecting line, then only one enemy is targeted. There are still some missing features, like the gem cost of the skills and its pattern. Plus the weapons loadout is a bit of a mess, so I might just make it look more like the skills loadout by reusing most of the same code.

Update:


Here is the improved skills loadout with gem costs and pattern. The cost is exaggerated for sake of illustration.

Updated Skills Loadout.

I threw in a new skill for the panda too, because most of the work is just filling out some data that specifies it; the systems in place take care of most of the work. It is not entirely data-driven because I have to specify what the computed gamma value does based on skill level, and, reflect it in the skill description as well.

Most of the code of a new hero skill that applies a beneficial buff.

Monday, April 23, 2018

The journey shall continue

I started this journey as a digital nomad about half a year ago. Best decision I ever made. This lifestyle is just so easy and it provides me continuous time to dedicate to my projects. In Chiang Mai I work everyday. About once a month I travel to a nearby city or country, where I put my laptop aside and connect with others and enjoy my surroundings.

Chiang Rai with Jason from London.

I am writing this blog entry in the Thai city of Chiang Rai which contains three notable Buddhist attractions that I explored with a spontaneous travel companion.

Wat Rong Khun in Chiang Rai, Thailand

Wat Rong Khun in Chiang Rai, Thailand

I felt a definite connection with the white temple "Wat Rong Khun". It suggests having to cross over hell in order to reach a more enlightened state. We can't have the good without the bad. I reacted from a relatively low point to attain an ongoing highest point ever, so I'm going to ride this out indefinitely. Life tends to have a way of turning sour quickly, but for now, this is pretty fucking sweet.. know what I mean?

Sand dunes in Mũi Né, Vietnam with Dominic from Montreal.

The journey shall continue. Onward to Bali Indonesia for a couple months followed by a long-term return to Vietnam as my home base.

Wednesday, April 11, 2018

Gameplay footage

I put together a quick clip of the battle gameplay. The recording is not the best quality, but it should at least demonstrate several features of the game.


I made a couple design changes prior to the recording:
  • Each hero (left) will do a basic attack if their assigned gem color is matched on the board. Previously they would simply roll a percent chance to attack, following the enemy's turn. This change speeds up the battles and feels more action oriented.
  • All creatures have green (poison) armor of 500 points for sake of demonstration. This armor is impervious, so will not affect the creature's life points until the armor is destroyed by incoming attacks of its color. Simple and easy to understand. Previously I only had physical and magical armor amounts, which would reduce incoming damage by a percentage; some creatures could be immune to specific elements. It was unclear and very confusing.
I'll have to add a feature later to help color-blind players discern the gem colors and their assigned elements. Color deficiency affects 1 in 12 men, and one in 200 women (source).
  • Orange: physical melee and range based attacks. Swords, bows, maces.
  • Red: fire.
  • Green: poison and heals.
  • Blue: cold.
  • Purple: arcane magic attacks, beneficial enchantments.
Now, I get to clear the main board and work on the main screen that contains all the features like character customization, inventory, stage selection, and upgrades.


So many possibilities. I will buy more art through the Unity asset store to help me with this task. I may want to have a map for stage selection and some large packs of metal or wooden interface objects like buttons and scroll screens.

In addition, I need to contemplate how to extend playability of the game. Zombie Guard is flawed in that the game is way too easy when going back to previous stages to collect all the outstanding loot. It basically dead-ends too, without advancement to harder difficulties once all the stages are beaten.

Saturday, April 7, 2018

Easing curves for game balance

To my casual readers, you may skip to the below section on Final Thoughts if the math here seems a bit intimidating.

For Unity you can download my Easings.cs script that borrows from tween.js on GitHub. A delegate for exact choice of easing function can be passed into your custom scripts.

Lerp and easing functions

I have been using easing functions extensively for many years, usually for animation. Easing functions are just curved functions for values $t$ from 0 to 1.

Linear is boring, but sometimes necessary to interpolation. Meaning, a value changes gradually - neither speeding up, nor slowing down as time $t$ goes from 0 to 1. Linear interpolation $lerp$ is a convenient function to compute this linear value:

$lerp(x_0, x_1, t) = x_0+(x_1-x_0)*t$.

Where $x_0$ is the initial value and $x_1$ is the final value as $t$ goes from 0 to 1. These values can be colors, vector positions, numbers, etc.

If $t=0.25$ then the value would be 25% of $x_0$ and 75% of $x_1$. If these are positions, then it would be 75% of the way from to $x_1$ starting from $x_0$.

Easing functions, from easings.net

To understand these functions, just choose one and slide your finger from the left and gradually to the right. If the point on the line is closer to the bottom horizontal line, then it is closer to the initial value. If it is closer to the top horizontal line then it is closer to the final value. Some functions can even go beyond the bounds of the initial and final values.

If we have a fireball in a game, then perhaps we might want to have its movement towards its target begin slowly, and then pick up speed until it explodes. In the second row of the figure above, are cubic functions. Notice how $easeInCubic$ would be very suitable for the fireball's movement. On the other hand, $easeOutCubic$, may seem a bit strange, where the fireball shoots quickly and then seemingly slows down before it explodes.

Game Balance


I use these easing functions extensively for game balance as well. In my game, weapons can be upgraded from ranks 1 to 10. At rank 1 it is the weakest, and at rank 10 it is the strongest and does the most damage. The easiest solution would be to just write the damage values manually.

Morning Star

For example, the damage of a morning star for each of the 10 ranks could be manually coded like this:
\[[1, 3, 5, 18, 13, 23, 50, 83, 88, 92]\]
But this gets confusing! It is too many numbers to work with. Plus, it is hard to immediately see the difference between each rank. Notice how the damage can go from 50 to 83, which is a 63% increase. That is massive and throws off the balance of the game. Also the damage at rank 4 is greater than rank 5.. oops! These errors can occur easily if we write the damage values manually.

Fail.
A generated graph of the damage of the morning star quickly illustrates the flaws.

We need a better solution...

In my game, weapons have an initial damage of $d_0$ at rank 1. In addition, a multiplier that determines the final value $dmul$, where for example a value of 4 would mean the damage at maximum rank would be $d_1 = d_0*dmul$, four times the initial starting value. Easy! The damage for the morning star now can be specified by just two values!

So, let's give it an initially large damage $d_0$ value of 42, but a tiny $dmul$ of 1.25, so fully upgrading it only provides an extra 25% damage increase.

The linear damage of the morning star for each rank would be $lerp(d_0, d_1, t)$ where $t$ is:

$t = (rank - 1)/(maxrank - 1).$

The linear damage increase is a bit unfair because a weapon casually upgraded to rank 2, would completely outshine a new weapon at rank 1. The game balance would feel off. In addition, upgrading from ranks 9 to 10 would provide the same damage increase as upgrading from ranks 1 to 2.

$easeInCubic$ looks like a good choice. So, the revised damage of the morning star would be:

$lerp(d_0, d_1, easeInCubic(t))$.

Similar to how damage is calculated, the cost of upgrading needs to be considered as well. Suppose we use the same curve, $easeInCubic$. This would not be balanced because it would be too easy to upgrade anything to around rank 7!

I think $easeInOutCubic$ would be an interesting choice for the cost of upgrades:
Better!

The cost for sequential upgrades always increases, but ranks 4 to 6 would have the largest increases in cost. This would be suitable because most weapons could casually be upgraded to around rank 4 until the costs get awfully pricey. Ranks 7 to 10 are where the costs are very high, but would be very rewarding due to the drastic increase in damage; there is an incentive to max it out.

Final thoughts


Balancing a game is a continued struggle. As written above, I have chosen an approach to help adjust the difficulty of my current game in order to feel balanced and rewarding to play. In-game currency is used to upgrade weapons from ranks 1 to 10. Here is the ideal mindset a player should have while upgrading these weapons:
  • Ranks 1 to 4: "Oh, these were easy upgrades. It feels like I am rich. I upgraded everything to rank 4! I like the slight increase in damage and I am not certain which weapons are my favorites. I just found some new weapons that still look powerful even at rank 1, so I will try those out too."
  • Ranks 4 to 7: "Woh, these upgrades are starting to get expensive! I must be more careful in how I invest my money. There does not seem to be a noticeable improvement on damage by upgrading these, but the enemies are starting to get really tough too."
  • Ranks 7 to 9: "All these upgrades are so pricey, but the damage is going way up now! It looks like the damage at rank 10 is twice as good as rank 7 so it is worth it!
  • Rank 9 to 10: "Well, it was a struggle to upgrade it to rank 9, but looks like it is totally worth maxing it out because it is the largest increase in damage of all the upgrades! Now I can choose something else to max out."