This week (and the later half of last week) was focused on building the town. This is the thing that stores your permanent progression, in the form of upgrades that can be applied to new characters. This gives an overall sense of progression to players, but also allows you to play an 'unupgraded' character simply buy not acquiring any upgrades. The town gets upgraded by completing quests out in the world (for example finding a iron mine upgrades the weapons the blacksmith will sell you). You can see the new starting tavern here.
Other changes this week:
New class 'Farmer'. This is your new starting class. The others are unlocked via quests.
New skill trees for the farmer. It has abilities like Plough Face and Sow Pain.
A load of new quests to do with upgrading the town, and some more not to do with that.
Removed default bonus stats from heavy/medium/light armour, now making it a speed/defense tradeoff. Also increased the likelyhood of enchants so there should still be the stat boosts.
Made weapon scaling have a falloff in effectiveness. Now stacking a certain attribute doesn't make you instantly op.
Enemies now scale up in stats the deeper you go. So a goblin on floor 20 will be a bit tougher than on floor 1.
Improved the keyboard controls slightly. You can now use abilities with the keyboard. Still can't navigate the menus with it though
First things first, after much deliberation I've renamed 'Chronicles of Aether' to 'A Skin of Others'. The original name as afterall only a placeholder, hence why it was so generic fantasy. This new name should hopefully evoke more curiosity in those that see it, and therefore be more memorable.
I made an itch.io to help with managing playable builds for A Skin of Others, that will be the place to find the releases as I upload them. I'm going to aim to update the build weekly, so keep checking up on there to get the latest.
In games the combat balance of the player vs the enemies is extremely important, as it defines how the entire experience feels. If done incorrectly it can make the game seem unfair, or simply dull. However if done correctly the game becomes an engaging experience that brings the player back time and time again.
With that in mind, how does one go about balancing your combat?
Well if you search about the subject online you see many sources discussing playtesting, spreadsheets and graphs. These are however tweaking mechanisms, the steps you run through to perfect an already built system. Without that system they are useless, merely introducing a layer of complexity that does not result in a finished product. So with that in mind, how does one build a combat system?
My technique for doing so is to think about the combat in terms of 'hits'. This is an abstracted version of health that refers to the number of times an entity must be hit before its considered dead. This value boils down the complex system of HP, attack, defense into what the player experiences, and allows you balance accordingly.
To figure out how many 'hits' an enemy should take you need to next decide on the flow of the game. Is it a fast paced game, where enemies die after only a few strikes? Or a longer turtling game where combat is a battle of attrition, with enemies requiring tens of strikes to be downed? Once you decide on the flow you can assign hit counts to enemies respectively. For a medium paced game a weak enemy could require 4 hits, and normal enemy 6 and a strong enemy 9.
We can further use the hits system to balance out our attacks. So a basic attack might deal 1 hit, a strong attack 2 hits, a special ability 4 and a ultimate ability 6. Another example using final fantasy attacks:
Basic attack = 1 hit Fire = 2 hits Attack, charged up = 3 hits Fira = 4 hits Firaga = 6 hits Limit Break = 8 hits
So this way we figure out the relative power of skills when compared to one another.
So how do we figure out what Hp, Attack and Defense to give our entities so they obey our hit counts? At this point here is how our game entities look:
Now we can make a little formula to figure out relationship between the other stats:
Hp = calculateDamage(Attack, Defense) * Hits. Which means the Hp will equal the damage formula (taking the attackers attack and defenders defense) times the number of hits that entity strength can take.
So to figure out the correct values for the formulas I like to start from deciding the amount of damage a 'hit' should entail. Lets say I pick a hit to be 10 damage. This makes the hp of our entities easy to figure out, 40, 60 and 90 respectively. We also now have an output value for the damage formula.
calculateDamage(Attack, Defense) = 10
Now the details of how you calculate the damage based on the inputs are entirely up to you. There are tons of examples of formulas floating around the internet to look at as an example, but you can read on to see what I use.
So in my game I determined that I want attack and defense to be a contest against one another. So when attack equals defense it should deal 10 damage (1 hit). If attack exceeds damage it should deal extra hits based on the amount it exceeds the defense by. If attack is less than defense it should deal only part of a hit, based on how far below the defense it is.
The values of attack and defense then only matter when compared to one another. I am basing the attack and defense value off the 'level' of the entity, so higher level things deal more damage and take less damage.
Anyway I hope this helps you plan out your own combat system!
Well it certainly has been a while since I posted anything on here. Work on Chronicles of Aether has been flying along, inching closer to a complete gameplay system that I can release as a playable demo.
Anyway here you can see what the game currently looks like:
This week I have been plotting out a series of ideas for how to add interactivity to the dungeon. Often the dungeon can feel flat and lifeless, an empty husk used simply as a container for enemies to wait to be slaughtered. I wish to dismiss this feeling and make the dungeon seem just as dynamic as its denizens. So to do that the player needs to feel that the dungeon itself can be interacted with, and the dungeon needs to change in meaningful ways in reaction. A few methods are outlined below:
Destructible Walls - Many roguelikes include the ability to dig through walls, allowing the player to tailor the dungeons layout to their needs. However this provides complications with many pieces of content where the entrance/exit are well defined, and the ability to enter at any point breaks it. This tends to be countered by 'undiggable' wall types.
Traps - A staple of roguelikes, traps activate some affect when triggered, often by being stepped onto. The most common traps are single tile direct damage traps, though more complicated setups are sometimes used. These can often feel cheap, as their short range nature require tricks to get the player to step onto them, like making them invisible.
Puzzles - An interconnected series of things that interact in some way, the a solution that provides some form of reward. An excellent method for adding interactivity to the dungeon. The issue being that generating a good, interesting puzzle can be very hard.
As interesting as these would be to add it was not what I started with. So the first task I completed towards dungeon interactivity is a thing I like to call 'Fields'.
Fields are a single tile area of some substance, that interact with other Fields (and the entities within them) in some fashion. For example a Fire that can be put out by pouring water onto it, turning the water into steam. These fields can be placed in the level by various methods, from an entities death (a spore releasing a cloud of poison gas on death), to a dungeon feature (smashing a fountain releasing a constant stream of water).
Like everything else in my game the fields are data driven, having a series of data points that define their properties. They are as follows:
Field name - This is the name of the field, used for checking if a neighbouring field is the same as this one
Tags - A list of tags that define the properties of the field, using for the interaction map (Examples are Hot, Cold, Gas, Poison, Explosive).
Stacks - A value representing the strength of the field.
Layer - The field 'layer' it exists on. Currently I have Ground and Air.
Duration Style - This defines its lifespan. I currently use Permanent, Fade (slowly reduces the stacks until the field disappears) and Collide (disappears on first collision with an entity).
Spread Style - This defines how the field spreads. I use Flow (flows out down the 'stacks' gradient), Adjacent (spreads to nearby tiles with stuff in them), Wander (randomly wanders around) and None (doesnt spread)
Field Interactions - A map of field name or tag to an interaction event. Currently supported interactions are Spawn (spawn a field of the specified type) or Propogate (applies some effect to every field tile joined to the src tile).
OnTurn - A list of effects to apply every turn. Examples are Damage and Healing.
An example of spreading fire:
Water putting out fire and turning into steam:
Lightning hitting water and propogating through it:
This week saw the introduction of sound into Chronicles of Aether.
Sound is immensly important in games as it provides one of the two main ways the computer can interact with our senses (the other being sight). With such a large portion of the players experience of a game relying on this it is a shame it tends to get neglected by developers so often.
In Chronicles of Aether sound is seperated into 3 main categories.
Music. Each level has a background song that plays, picked to evoke an emotion that reflects the design of the level. For example a foreboding eerie track for a crypt, or a happy jaunty tune for a bright forest.
Ambient sounds. Sounds that play due to some logic (such as repeat infinitely, or once every 10-20 seconds etc). These are used to give a further depth to the atmosphere building for the level. Examples are groans and echoing splashes for a dungeon, Birds and insects for a forest.
Effect Sounds. These are sounds that play in reaction to some action an entity in the world has made. An example being the sound of a sword strike or a fireball explosion.
After implementing these sounds I had entities exclaiming when they saw an enemy, groaning when they were wounded, and a cacophany of other sounds as they bashed each other to death. Sitting back I looked at this scene a realised it felt contrived, all this noise that meant nothing to anyone but the player.
Then I had an idea. Why don't I add meaning to the sounds, something that the entities can act on? With this in mind I added a piece of data to each of the dynamic sounds. Entities close enough to hear the sound would have that data inserted into their ai, to process as they will. Suddenly the world came alive. Sounds of fighting would draw in nearby entities to investigate, enemies would shout out the location of the player, informing their allies of the players position and calling them forward. Wounded creatures could inform their healer allies that they needed assistance. And every piece of this interaction was perceivable to the player, as they could hear the creatures talk to one another.
Now I'll get quickly into how this is implemented:
Background and ambient sounds have no in game meaning other than to create atmosphere, and therefore the code playing them is very simple.
Sound effects have a few different configuration settings:
Max Volume. This is the maximum (before attenuation) volume.
Max Range. This is the range where attenuation will have brought the volume to zero.
Attentuation Offset. The range value to start attenuating from. Anything below this plays at max volume.
Data. The data to impart to the entities who hear it.
Whenever a sound is played it gets all the entities within a sphere around the source defined by the maximum range. Then for each entity it tries to path towards it using AStar. If it can find a path with less steps than the maximum range that entity 'hears' the sound and gets the data.
It does the same for the player, to calculate the volume for the sound to be played at.