Data entry in roguelikes
By: Santiago Zapata / SZDev-Slash
Version 1.2: May 13 2006
If you work hard enough, you may get your engine to an eventual finished state, and you will be confronted with the difficulties of making an actual game; this includes creating an adequate setting or plot, deciding on the rules of the world and the actual data for the beings and item definitions.
The first approach for these definitions is to first program the different game interactions, and then balance the mechanics via trial and error; while this has been good enough for most games out there, in this document I present this simple way, which may be well suit for a kind of game with strong rules and consistency.
First Step
The first step is crucial to the method, and consists on stating clearly the attributes for both items, beings and other entities that will affect the execution of a certain interaction. This must be done individually for each action you plan to implement, posibly looking forward to share attributes in different actions to keep the list handable.
For example, for the implementation of a simple ‘Combat’ Action, you may decide that your variables to calculate the ‘Strength of the blow’ are:
- The ‘strength’ of the performer
- The ‘proficiency’ with the given weapon kind
- The ‘strength’ of the weapon
You will also need to calculate the chance for the blow to fail, and state the following variables:
- The dexterity of the enemy
- The weight of the enemy
- The evade bonus of the enemy, based on his equipped accesories
Finally you will need some sort of health, so that the final effect of the blow is perceived.
Second Step
The second step is to draw a scale and locate the different actors types of your world on it, depending on the setting you have created.
For this example first variable (Strength of the performer) you could come up with something like this:
Strength of the performer | |||||||||||
Performer | d | @ | c | b | D | ||||||
Scale | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Performer | |
d | dog |
@ | human |
c | cow |
b | bull |
D | Dragon |
My recommendation is to keep the list small, containing only the most differenciable kind of beings, and try not to have ‘holes’ in your scale in order to consider all the extreme cases..
Repeatinf this for the rest of your variables, using your subjetive opinion on the different entities, we get:
Profficience with weapon | |||||||||||
Profficience | None | L | M | H | |||||||
Scale | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Weapon Strength | |||||||||||
Weapon | Le | Co | St | Ir | Go | Ad | |||||
Scale | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Weapon | |
Le | Leather Whip |
Co | Cooper Sword |
St | Steel Axe |
Ir | Iron Sword |
Go | Golden Halberd |
Ad | Adamantium Dagger |
Third Step
The third step consists on making a scale for the final possible values for the variable we are calculating. In this example, that would be the ‘Strength of the blow’
Damage | |||||||||||
Gravity | No | De | Tr | Gr | Ar | Cr | |||||
Scale | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Gravity | |
No | No damage |
De | Deprecable damage |
Tr | Treatable damage |
Gr | Grievous damage |
Ar | ‘Urgent Attention Required’ damage |
Cr | Critical Damage |
Fourth Step
The fourth step is to ennounce different axioms from the ‘reality’ you crafted for the game; these axioms are based in the subjetive values on the scales you have created.
For example:
- If a ‘human’ with ‘mid battle proficience’ slashes with a ‘steel sword’, he will cause ‘Treatable Damage’
- If a ‘bull’ with ‘low battle proficience’ hits with a ‘iron sword’, he will cause ‘Grievous Damage’
You will need axioms for the extreme cases
- If a ‘dragon’ with ‘high battle proficience’ hits with a ‘cooper sword’, he will cause ‘Critical Damage’
- If a ‘dog’ with ‘mid battle proficience’ slashes with a ‘leather whip’, he will cause ‘No damage’
Mapping this to a table we obtain:
Strength | Profficience | Item Strength | Damage |
6 | 6 | 6 | 4 |
8 | 3 | 8 | 6 |
10 | 10 | 3 | 10 |
3 | 6 | 2 | 0 |
You must balance the number of axioms you ennounce, as the final equation will be more accurate if you have any axioms, but you risk on failing into inconsistences from your subjective point of view, as we will see later.
Now watching the table we see that Str and Prof have an higher weight in the resulting damage. We can do two things here:
- Make only Str and Prof relevant for an intermediate ‘Damage’ calculation, and then apply the Item Strength as a bonus factor for the final ‘Strength of the Blow’ value.
- Proceed assigning a higher weight to Str and Prof into the ‘Strength of the Blow’ calculation.
Let’s decide for the first option, and for the sake of simplicity calculate a damageIndex as an average for Str and Prof
Damage Index | Damage |
6 | 4 |
5.5 | 6 |
10 | 10 |
4.5 | 0 |
Here we see an inconsistent result: a damage index of 6 is causing less damage than one of 5.5? For some variables this may be a desired result, but this is not the case, as we expect the damage to be in direct proportion with the index.
In this case this is happening because of the simple average operation we used, as Str has more weigth than Prof for the damage. We then calculate a weigthed average, using ((Str*2)+prof)/3
Damage Index | Damage |
6 | 4 |
6.333 | 6 |
4 | 0 |
10 | 10 |
Ok, this looks more like it.
Fifth Step
The fifth step is to calculate a polynomial tendence of an appropiate degree for these variables. We observe the tendence line and analyze its consistency; this means no “zigzags” (relative maximums or minimums) for most variables if not all of them, unless your game shows some kind of surrealism on its rules.
If the results are not satisfactory, analyze the damageIndex calculus further, check your axioms for consistence or change them for others with a wider scope.
For this example we get the quadratic regression
damage = -0,1747(damageIndex^2) + 4,1268(damageIndex) - 13,778
Let’s not forget about the itemStrength variable. We may assign it as a bonus as show in this scale:
Item Strength | |||||||||||
% Bonus | Le 110% |
Co 150% |
St 200% |
Cr 400% |
|||||||
Item Strength | 1 | 3 | 6 | 10 |
Using a quadratic regression, we get
bonus = -0,0001(IStr^2) + 0,0973(IStr) - 7,7779
And then, our final results:
damageIndex = ((Str*2)+prof)/3; damage = -0,1747(damageIndex^2) + 4,1268(damageIndex) - 13,778 bonus = -0,0001(IStr^2) + 0,0973(IStr) - 7,7779 finalDamage = damage * (bonus/100)
Usages
So, what is the use for this method on data entry?
After you get consistent results using your “test” beings and items, you may proceed to locate your collection of entities into the scales, using your subjective opinion.
Strength of the performer | |||||||||||
Performer | s | f,r | d,S | i | g,w | @ | c,o | b, T | D,W,A | ||
Scale | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Performer | |
d | dog |
@ | human |
c | cow |
b | bull |
D | Dragon |
i | imp |
g | goblin |
o | orc |
f | fairy |
s | slime |
T | Troll |
S | ice Snake |
W | Wyrm |
A | Angel |
r | rattlesnake |
w | wolf |
This way, by assigning a position for each entity on the scales, you will get consistent results.
Notes
There are some variables that you may need to scale down before attempting to calculate the index to get simpler equations. For example, if you are calculating the spaces that an item will be pushed
after being kicked, you will need to have in mind the weight of the object, which may not be in the same proportion of the kicker strength.
Also, for some results you will have to invert the variables, for example, objects with less weight fly more spaces when kicked.
Version History
1.2 – May 13 2006 | HTML, cleanup |
1.1 – January 22 2006 | Clean Up and better examples. |
1.0 – January 10 2005 | First Version |
One thought on “Data Entry in Roguelikes”