Once I’d got the basic design down for unlocks and modifiers, the next step is to figure out how this is actually going to be implemented. The idea here is that we have two aspects that are technically separate:
- Things that can be unlocked (Spells)
- These cost resources
- These take time to unlock
- When unlocked the apply modifiers to certain actions
- Spells can affect multiple buildings
- Some of these actions should possibly be temporary
The specific example we’re going to start with is a ritual of minor fertility that costs 1000 herbs and 1000 flowers, takes 1 minute and gives a permanent 10% bonus to herb gardens and flower patches.
Because I’ve chosen to have unlocks cost time as well as resources, there’s a natural place to put these in my architecture: Actions. There’s no reason why I can’t have a player action that casts spells. While for this game I’m branding these actions as spells, I can see that not all unlocks are going to be spells in the future, so for my own sanity I’m calling it research (a similar thing would be the gather action – if I implemented write scrolls as an action, it would still internally be gather scrolls. Similarly, buildings produce resources by gathering them, even though that’s not how it would be termed in the game)
Research is then an action that as it’s end result adds a research type to the list, and applies the modifiers from that research to the rest of the game. There’s some special features about this action however:
- It has (optionally) a cost to start
- It can only be started if it’s not been started before
- Once it is finished, it is not restarted
- It doesn’t produce any resources
These are easy enough to cover though. The start conditions can be covered by checking we can start the research when we receive a request to set a player action in the web worker. If we don’t meet the conditions (we don’t have the resources or the research is complete) then we simply refuse the change (and send a message back to the main client to indicate this)
The other parts are simply making resources optional when the action is complete, and when the action is complete we set us back to the forage action, which is always a safe action. If we really wanted bonus points, we could remember the player’s previous repeatable action and go back to that instead, but forage is a simpler and safe result for now.
The next step is to apply modifiers to the actions. Once the research is complete, we apply a modifier to some of our buildings based on the building type. This should be a generic structure that can be reused – we are planning to have a lot of different choices of spells that can be cast! So, as part of the unlock process, we’ll look at all the buildings and check to find out if we have a suitable modifier. Then we add the modifier to the list of modifiers for that building.
When the building’s action resolves, the modifiers to the results will be applied, so any resources added to the action results, and all the scale factors multiplied together, then applied to the resource total after everything is added.
So to implement this we just need to add a few features to our actions (checks causing us to refuse to accept the new request, new data for research type, new one-shot behaviour) and we have an action that unlocks a research – so this is the first part of doing a ritual of minor fertility.
The second part involves finding a modifier and adding it to the building list, then applying it.
To find the details of the cost and the action required, we create some static data structures which store this information – the research rules. These would look like:
Research( type = ResearchType.RITUAL_MINOR_FERTILITY, cost = mapOf( ResourceType.HERB to 1000.0, ResourceType.FLOWER to 1000.0), time = 300.0, modifier = Modifier( type = ModifierType.RESOURCE_MULTIPLY, resourceScale = 1.1 ), buildings = listOf(BuildingType.HERB_GARDEN, BuildingType.FLOWER_PATCH) )
Then, during our action, we check our rules to make sure we have the required cost, and if so create an action with the given time.
When the action is complete, we apply the modifier to any building actors which match the types given.
We could also go through the list of all research in order to regenerate all the modifiers. This would be used when we load the game from a save, or when we create a new building for the first time. It might be sensible to do this anyway, to offer a safety net in case we accidentally add a modifier at the wrong place.
Conclusion and Next Steps
The design above is fairly simple and wasn’t massively difficult to implement. The biggest problem is feeding all the various bits of data through the message buffer. The end result is that we have a research that is fairly generic, so it should be relatively easy to add new options to it and add some much needed complexity to the game.
There is a concern with the fact the interaction costs resources and time.
- What if a player changes action during a research action? They would lose the resources they used to start the action, which could be very expensive. This would definitely need some confirmation.
- What if the player managed to click twice on the same research button? Would they be charged twice?
- What if the player can only play occasionally? Are they going to be punished for only playing daily because they can’t click on the next research task?
I also have some more work to do here in terms of what is available – some spells should not be available until other spells have been cast or other game conditions have been met.
So there’s quite a lot more that can be done here, but the basics are there.