We have actor stats now! I’ve nearly finished this feature – I only have display left to do, and although there’s some balance issues I need to solve, that can wait until there’s more game to balance it around.
The purposes of actor stats were the following:
- For a story driven player, it gives the player a sense of accomplishment and achievement that their character has got better, and to give a sense of ownership of the character.
- For a gameplay driven player, it gives the player a permanent bonus that can be carried over resets.
- Also they allow the creation of other non-player actors (eg familiars), which would be better suited to certain roles .
I also wanted these to be familiar, so I was going to stick with the established RPG model of stats; stats have experience and you improve them with use. This made the design pretty easy really:
- An actor has an set of stats associated with them
- Actions have stat effects associated with them, reducing the time taken or increasing the resources gathered
- Actions also have stat training effects which give experience to actions
- Stats contain experience points (XP) and a level
Stats usually have an “experience curve” – ie when you get enough XP to get a level , it takes more XP to get to the next level. This means you have diminishing returns from the time invested, but also allows the game to offer more experience for actions later in the game.
I decided for this game that level would simply be derived from total XP, rather than XP being “spent” to gain a level.
Since I can’t really balance the game carefully at this point, I decided on a simple square root as the basis for my curve. This gives a simple diminishing return, without giving the excessive numbers of an exponential curve. In order to make the numbers a bit bigger, I made 1000 XP the requirement for the first level, so the level formula is floor(sqrt(XP / 1000))
The implementation here is pretty simple, although first I had to move the action rules into a structure. Then, every action rule has a list of StatEffect structures:
class StatEffect( val stat: StatType, val timeEffect: Double = 0.0, val amountEffect: Double = 0.0, val train: Double = 0.0)
At the start of an action, the timeEffects for each stat are added together to reduce the total time for the action, and the amountEffects are added together to increase the results.
- Each stat effect factor is multiplied by the level (they must all be positive; we’ll have to worry about negative effects later)
- Stat effects added together and 1 is added to it, so we have a scale factor or if we have no levels in any relevant stats, then the scale factor will be 1.
- If this is for time, we want to reduce the time, so we invert it ( 1 / factor) to reduce instead of increase.
- Then we multiply the factor by the amount or max time.
Note that we’re adding together different stat effects rather than creating a scale factor for each and multiplying them. This means that they won’t give too big a bonus if you have several stats affecting an action.
These stat effects are calculated at the start of the action. This means any temporary stat boosts (eg via rituals) will only need to be active at the start of the action.
The last part of the implementation is training. This is done at the end of the action, and again is pretty simple:
- We look up the rules for the action we just completed to get the stat effects
- For each stat effect with a training value, we increase the experience for that value by that amount.
We don’t need to worry about scaling this; when we write the rules for an action, we can take into account the length of the action and award more experience, etc.
Having a training effect allows us to have a training action; this would simply be an action that produced no resources, but would specifically have stat effects to train a stat.
This is very nearly done now, but we still need a way to display the stats to the player, in order to meet the first point of our design goals. However, we have completed the second point; we now have a real bonus that can be gathered by a player and as stats are not reset on soft reset, this is a permanent bonus.
The third point from the design might still need some thinking about. At the moment stats only give small bonuses, but it would be useful to have a familiar that was vastly better at gathering wood but terrible at gathering herbs, for example. For this perhaps I would have negative stat effects, so that I could make a familiar start with a very large negative level for herbalism, for example, so it would gather a lot fewer and much slower.
Overall, though, we have a foundation on which we can build, so I’m quite happy with where I’ve got to so far. Once I’ve added a basic display feature, actor stats are finished for this release, and given that I’ve done quite a lot of the action improvements for actor stats, that means I’m quite close to my targets for 0.4.0!